MS.Tech - IT人

.NET & 微软企业服务器 & 前沿技术和产品
随笔 - 107, 评论 - 1269, 引用 - 87

导航

关于

所有内容和观点仅代表个人观点,如有问题和建议请发Email给我。

标签

每月存档

最新留言

广告

VS2005中的Project Templates

在前面发表的一篇〈GridView中显示数据库里的图片〉里提到ASP.NET 2.0里提供的几个Starter Kits fot VS2005,于是有人MSN问,几个Starter Kits应用程序均以“.VSI”扩展名的文件提供,这是个什么样的扩展名?为什么我们可以直接安装,并可以把Starter Kits应用程序项目直接嵌入VS2005中的新建项目模版里?

确实是个有趣的问题。VSI,如果我没理解错的话,应该是Visual Studio Installer的缩写。那么,.VSI文件到底如何实现在VS2005里嵌入项目模版的呢?这个要从VS2005提供的“Export Template”说起了。Export Template项在File菜单里。我们动手从一个例子看起吧。

1、新建一个ASP.NET Web Site。并编写你打算作为日后模版项目里固有功能的代码,也可以放置任何文件夹和文件,比如图片等。这个Web Site在后面将成为VS2005里的一个项目模版,类似Starter Kits里的那几个示例。下面是演示项目的一张图片,供一会与利用该模版新建的项目对比,看是否完全一致。

2、保存项目。然后在File菜单中选择“Export Template”,弹出如下对话框。我们选择第一项“Project template”。最下面的模版类型选择“Visual C#”,表示创建的是C#的ASP.NET Web Site模版。当然你可以依照你喜好选择VB.NET。

3、选择下一步Next。进一步设置模版图标、模版名称、说明等。这些基本属性信息将作在VS2005里显示给用户看。

4、按“Finish”结束导出过程。同时如果你选择“自动嵌入Vs2005”,按Finish后,你在新建WebSite项目的窗口里,就可以看到你刚才所创建的项目模版,如下图。如果你选择最下面的“Display an explorer......”还会自动帮你打开输出目录。在选择利用这个WebSite1项目模版创建的项目,将自动包含第一张图里所列的所有文件夹和文件和所有代码等,即完全是第一张图项目的克隆版本。

至此,完成了Starter Kits里最终一样的效果。但是.VSI的疑问还是没有解开。别急,其实我们已经快解开这个VSI疑团了。现在,进一步再看刚才我们导出的项目模版文件WebSite1.zip,默认在C:\Documents and Settings\Administrator\My Documents\Visual Studio 2005\My Exported Templates目录下。我们发现刚才导出的文件居然是个.ZIP的压缩文件,于是很自然想到解压缩看下里面有些什么东西。解压缩后发现除了原本项目里所有的文件夹和文件外,还多了一个模版图标__TemplateIcon.ico和一个名为MyTemplate.vstemplate的文件。利用记事本打开MyTemplate.vstemplate,里面内容为一份描述这个项目模版信息的XML数据文档。(文档内容略)。

正是这份XML文档让我有了一个想法,即利用UltraEdit打开StarterKits里的TimeTracker.VSI文件察看内部结构,发现果然是个ZIP压缩包文件。于是将StarterKits里的TimeTracker.vsi改名为TimeTracker.ZIP,顺利对TimeTracker.ZIP进行解压缩。TimerTracker压缩包里除了一个跟我们上面制作过程一样格式的ZIP文件外,还包含了一个TimeTracker.vscontent的文件。再用记事本打开这个vscontent文件,真相大白:

<?xml version="1.0" encoding="utf-8" ?> <VSContent xmlns="http://schemas.microsoft.com/developer/vscontent/2005"> <Content> <FileName>TimeTrackerCS.zip</FileName> <DisplayName>Time Tracker Starter Kit (C#)</DisplayName> <Description>Starter Kit for Web project (General category)</Description> <FileContentType>VSTemplate</FileContentType> <ContentVersion>1.0</ContentVersion> <Attributes> <Attribute name="TemplateType" value="Project"></Attribute> <Attribute name="ProjectType" value="Visual Web Developer"></Attribute> <Attribute name="ProjectSubType" value="CSharp"></Attribute> </Attributes> </Content> </VSContent>

原来.VSI文件内部只有两个文件:一份用于描述文件信息的XML文件和一个利用Export Template导出的ZIP压缩包。

了解了VSI内部结构后,我把TimeTracker.vscontent里的这份XML文件信息更改为描述WebSite1的信息,主要把FileName改为WebSite1.zip,然后顺便把TimeTracker.vscontent也更名为WebSite1.vscontent,然后压缩WebSite1.vscontent和WebSite1.zip文件为一个新的WebSite1.zip(注意只有ZIP压缩文件才被接受),最后把新生成的WebSite1.zip更名为WebSite1.vsi。然后双击WebSite1.vsi,其安装过程和结果完全与StarterKits里的示例一致。至此,VSI疑团告破。

认真想一下这个模版输出功能,确实大有用处。程序员之间可以利用VSI文件进行真正便捷、可配置的代码交流;也可以利用项目模版创建一系列公用的应用程序模版。相信,不久的将来,大部分.NET社区或网站提供的.NET代码示例都会采用类似Starter Kits的做法,也相信大家的代码程序交流将会更加倾向于这种VSI文件之间的交换。

再补充一下:呵呵,发表了以后,再去google查了相关资料。才发现.vsi扩展名文件的安装,其实质是调用C:\Program Files\Common Files\Microsoft Shared\MSEnv目录下的VSContentInstaller.exe进行安装的。所以如果你出现不能直接双击安装.vsi的错误时,可以利用这个命令行文件进行安装。但是我还没有找到可以用来打包生成vsi的工具程序。但根据查阅的资料显示,利用Microsoft.VisualStudio.VSContentInstaller.dll(与VSContentInstaller.exe同目录)里提供的接口似乎可以自己编写程序创建一个vsi打包工具,但尚未经过实际验证,有空再试试。

posted on 2005-08-17 21:00:00 by liuhuimiao  评论(4) 阅读(6485)

101 Samples for Visual Studio 2005

101 Samples里提供的DataAccess示例,也反映了ADO.NET2.0对于数据访问这块的一些变化。DataAccess共包含14个示例,每个示例名称都直截了当说明了该示例的主题。

  • Asynchronous Queries:异步数据库查询。
  • Attaching a database with your application
  • Creating and using User Defined Types with SQL Server 2005
  • DataReader vs. DataSet comparision
  • DataSet and DataTable Enhancements
  • Performing Batch Updates and Data Paging:批量更新和数据分页的性能分析
  • Performing Bulk Updates:批量复制数据的性能分析
  • Reading and Writing Images from a Database:
  • Using Factory Classes:介绍利用System.Data.Common命名空间里的DbProviderFactories类来动态创建数据库连接对象。
  • Using Managed Stored Procedures and User Defined Functions with SQL Server 2005
  • Using Multiple Active Result Sets with SQL Server 2005
  • Using Notifications with SQL Server 2005
  • Using the XML data type with SQL Server 2005
  • XPath and XSLT Transformations Enhancements

首先,对于Asynchronous Queries,在该示例中提供了Polling、CallBack和Wait三种方式来演示异步数据查询功能。但根本的都是得益于ADO.NET 2.0中SqlCommand的BeginExecute...EndExecute...异步功能。比如Polling方式,其数据库连接串为:

Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Databases\Data.mdf;Integrated Security=True;User Instance=True;Asynchronous Processing=true

实现的具体C#代码:

// We use the BeginExecuteReader which returns a IAsyncResult // which can be polled to see if it's complete IAsyncResult myResult = myCommand.BeginExecuteReader(); while (!myResult.IsCompleted) { // do something } // After the result finishes, we can end the reader SqlDataReader myReader = myCommand.EndExecuteReader(myResult);

这个数据库异步查询功能还是比较实用的。接下来的批量更新和批量复制更是日后我们在ADO.NET2.0编程常用的特性了。SqlBulkCopy,即数据批量复制可以让我们很方便地把数据从一个数据源迁移到另外一个数据源去;BatchUpdate则允许我们一次性更新多条数据,从而提高系统性能。下面先看Batch Update代码:

// Batch Update for (int i = 0; i < myNumberofRows; i++) { // For each record inserted, we have to create a new row DataRow newRow = myDataTable.NewRow(); // Give it some value newRow["ID"] = i; newRow["value1"] = i * 10; // Add the new row to the DataSet myDataSet.Tables[0].Rows.Add(newRow); } // After all the new rows have been added to the DataSet, we can update the database. // Since we are inserting, all the rows that have been added, will be updated. myDataAdapter.Update(myDataSet,"SampleData"); // We want to explicitly show that the changes have been accepted to update the database myDataSet.AcceptChanges();

在BatchUpdate后,如需要在批量更新操作结束时进行一些其他操作,比如提示使用者批量更新已经完成,可以写RowUpdatedHandler事件:

myDataAdapter.RowUpdated += new SqlRowUpdatedEventHandler(RowUpdatedHandler);

这个示例比较有趣的还是性能分析这块。对于1000条数据,如果我们每次插入1条的话,平均大约要花1200ms左右;而如果我们每次插入的数据提升到50条的话,平均大约耗时1000ms左右。对于5000条数据,如果我们每次插入1条记录的话,平均耗时大约5500ms左右;而如果换成每次插入50条,则大约4500ms左右,相对每次插入1条的情况提高了近1秒;而如果换成每次插入500条,则耗时约3600ms左右,较前者又提升了一点。可见利用好BatchUpdate是可以提高一定的系统性能的。

而对于SqlBulkCopy批量复制,主要是利用System.Data.SqlClient.SqlBulkCopy类进行相应的处理,如想深入了解可以看示例。

最后,对于需要动态选择后台数据库,动态创建数据库连接对象的人来说,ADO.NET 2.0里提供的Factory Classes是个很好的消息。该功能主要是利用System.Data.Common命名空间里的DbProviderFactories类来动态创建数据库连接对象的。代码示例为:

// Get the connection settings from the configuration file based on the name selected // in the ComboBox ConnectionStringSettings myConnectionSettings = ConfigurationManager.ConnectionStrings[myName]; // Create an instance of the DbProviderFactory by using the Provider name in the config file DbProviderFactory myProvider = DbProviderFactories.GetFactory(myConnectionSettings.ProviderName); // Create the connection from the DbProvider factory, this code does not need to change for // for different providers DbConnection myConnection = myProvider.CreateConnection(); // Get the connection string from the connectionsettings // This gets us the specific provider by which we will connect myConnection.ConnectionString = myConnectionSettings.ConnectionString; // Open the connection myConnection.Open(); // now we can create the DataAdapter and then create a command DbDataAdapter myAdapter = myProvider.CreateDataAdapter(); DbCommand myCommand = myProvider.CreateCommand();

为什么要专门再从101 Samples里搬出这些来说。因为我觉得这样可能会节省大家一点时间,而且有部分人还没有或没接触VS2005。在这里抛砖一下,也让大家一目了然101 Samples里到底有哪些新鲜。相信花自己一点时间,节省大家多点时间,对比起来还是挺划算的。就像纽约时报的一篇文章《Spending Time to Save Time〉,其说的就是如果你要节约时间,那么你必须先花点时间去研究如何节约未来的时间。今天花一个小时,节约未来每天的哪怕一分钟,都是值得的。同理,花自己的一个小时,节约大家几秒钟时间,也是值得的。

posted on 2005-08-16 01:41:00 by liuhuimiao  评论(5) 阅读(6410)

101 Samples for Visual Studio 2005

101 Samples for Visual Studio 2005对于想要快速了解Visual Studio 2005新功能的开发人员来说,是个非常棒的选择!其提供的例子分布于Base Class Library、Data Access、Web Development and Windows Forms四个方面,每个方面内的每个例子都对新增的功能有很好的代表性和表现性。先看看Base Class Library。Base Class Library里一共10个例子,分别为:

  • ACLChange:访问控制的变化
  • Compression:新增的System.IO.Compression命名空间,主要介绍利用GZipStream类进行压缩和解压缩。
  • Console:2.0里的Console新增功能。比如现在可以在Console里设置命令窗口的Title标题、Size大小、Color背景色和字体颜色、Cursor光标等。
  • DriveInfo:驱动器信息。
  • FTP:现在System.Net命名空间里新增了FtpWebRequest类,用来进行FTP的相关操作。
  • GenericsSample:.NET2.0范型的示例。这个例子不错。主要演示了利用范型和普通集合类在类型安全操作和迭代时所花的时间的比较。
  • Network:网络相关。主要是新增命名空间System.Net.NetworkInformation的一些类的用法。
  • RegularExpressions:正则表达式,更强大了。
  • Stopwatch:这个演示的功能实用。主要介绍了System.Diagnostics里的Stopwatch类,该类主要用来计算某个代码段执行所花费的时间。省去了我们自己去设置开始执行时间和结束时间,然后相减得出最终代码执行所花费时间的过程。这点对程序员来说是比较实用的。
  • Transactions:主要是新增的命名空间System.Transactions的介绍。

对于GenericsSample这个示例,它事先声明了两个变量:

private ArrayList _unsafeList; private List<Order> _safeList;

然后从一个CheckListBox源中读出 object 类型项值,填入上面两个集合中。这时候,对于 ArrayList 类型的 _unsafeList 来说,自然不需要其他额外操作,直接插入CheckListBox读出的项值即可。而对于 List<Order> 类型的 _safeList 来说,自然必须指定为类参数为 Order 方可插入,于是就发生了casting操作,把 object 类型 cast 为 Order 类型,但是这却保证了类型安全。也就是第一个演示的目的。

对于测试二者性能的第二个演示,实质就是让二者各自迭代十万次,然后利用Stopwatch去计算出二者各自花费的时间,从而做出比较。这段代码是这样的:

private void IterateSafeList(List<Order> list) { // No casting needed foreach (Order _order in list) { long _amount = _order.Amount; DateTime _orderDate = _order.Date; int orderID = _order.ID; } } private void IterateUnsafeList(ArrayList list) { // have to cast from object to order foreach (Object _object in list) { Order _order = _object as Order; if (_order != null) { long _amount = _order.Amount; DateTime _orderDate = _order.Date; int orderID = _order.ID; } } }

 然后进行十万次迭代和计算花费时间:

            List<Order> newSafeList = new List<Order>(); ArrayList newUnsafeList = new ArrayList(); Stopwatch stopWatch = new Stopwatch(); long loadSafeListMs; long loadUnsafeMs; long iterateSafeListMs; long iterateUnsafeListMs; stopWatch.Start(); for (int i = 1; i < 100000; i++) { Order newOrder = new Order(i, DateTime.Now, i + 100); newSafeList.Add(newOrder); } stopWatch.Stop(); loadSafeListMs = stopWatch.ElapsedMilliseconds; stopWatch.Reset(); stopWatch.Start(); for (int i = 1; i < 100000; i++) { Order newOrder = new Order(i, DateTime.Now, i + 100); newUnsafeList.Add(newOrder); } stopWatch.Stop(); loadUnsafeMs = stopWatch.ElapsedMilliseconds; stopWatch.Reset(); stopWatch.Start(); IterateSafeList(newSafeList); stopWatch.Stop(); iterateSafeListMs = stopWatch.ElapsedMilliseconds; stopWatch.Reset(); stopWatch.Start(); IterateUnsafeList(newUnsafeList); stopWatch.Stop(); iterateUnsafeListMs = stopWatch.ElapsedMilliseconds; stopWatch.Reset();

经过运行得出,LoadSafeList比LoadUnsafeList花费时间多。而对于IterateSafeList和IterateUnsafeList,二者几乎差不多,一般前者比后者快那么点,但并不太明显。为什么会这样?留着大伙自己去理解了。

总体来说,101Samples赞,赶紧去down个下来看看。

posted on 2005-08-15 01:00:00 by liuhuimiao  评论(1) 阅读(5359)

Windows Vista Beta1体验

前阵子花力气载下了Windows Vista Beta1和Visual Studio 2005 Beta2 July CTP两个共近6G的软件。因此,一载完自然就热血沸腾想安装上去瞧个究竟,以补偿漫漫长夜载东西的郁闷。这里我们先尝鲜Windows,看看Vista吧。

我是在我原Windows XP SP2上用虚拟光驱安装Vista的。Vista要求全新一个分区安装,不能在现有操作系统上升级安装。Vista的安装相对以前版本的Windows确实改进了不少,没有以前那么多的步骤和停顿。在复制好所有文件到硬盘后,系统进行了一次重新启动,然后进入Windows准备初始化。在出现Windows图标和Codename Longhorn文字后,突然硬盘没有了反映,屏幕保持进入Windows前的黑屏状态,而这又不是死机。经过我反复几次重启,现象依旧。我开始怀疑是不是虚拟光驱安装的问题,于是我重新进入WindowsXP,把虚拟光驱里的Vista所有文件拷贝到硬盘中某个目录里,准备从硬盘里安装。但是后来那个该死的Vista安装程序丢了个大大错误提示框给我:“stub loader for setup program has encountered a problem and needs to close”,这个说明从硬盘安装Vista似乎行不通,于是只好重新利用Virtual CDROM安装。但是为什么在看似一切都正常的情况下,会出现Loading Windows卡壳呢?

由于我的Vista虚拟光驱是在我的一个40G的USB移动硬盘上的,在复制好所有文件到电脑内置硬盘里后,也即Windows Vista开始初始化硬件和安装信息时,出现了卡壳。在一个偶然机会下,我面对着黑屏愤怒拔了移动硬盘,啊~,电脑内置硬盘灯一下亮了起来,Windows又开始继续Loading了,直至下面的全新的Vista界面出来。后来经我反复拔插USB移动硬盘,总是这种情况: 插入时Vista就卡壳,即使是已经在Vista里面了。而拔出时一切就又恢复正常。这不知道是不是Vista硬件支持不好,还是BUG?

进入Vista后,第一眼感觉就是黄绿色桌面背景和暗黑色任务栏搭配起来,看上去挺舒服的。打开左下Start菜单,发现所有程序已经不再是一个展开的二级菜单,而是直接嵌套在了Start菜单左边栏里了,显得更加专业,空间也更加紧凑。另外,注销和关机则相反多了一个小箭头,通过它可以拉出一个菜单,进行相应选项。比如Shutdown里有StandBy、Hibernate、Shutdown、Restart和最底下的Options菜单。这样我们就不必再类似WindowsXP点击Shutdown后出现一个对话框让你选择是关机还是重启等,而可以直接一步到位的选择相应操作,这点对于讨厌多余窗口的人来说,是个不错的改善。在这个Start菜单中你还会在Lock和Shutdown左边发现一个搜索栏和搜索按钮。这个改进,其实就相当于把任务栏里的搜索条或者IE浏览器中的搜索条也搬到了大家常用的Start里,也体现了Vista搜索无处不在的特征。

         

再转过来看下桌面,我设置在桌面上显示“我的电脑”等图标后(噢,等下,我的电脑现在不叫My Computer了,而直接称呼为Computer,相应的,My Document也叫Documents了。也许微软觉得没必要再强调My了,毕竟在这个处处互联的网络时代,强调个人PC时代的My意义也不太大了),哇~,桌面图标好大个,一种很粗旷的感觉。这点对于习惯于1024*768分辨率中的小巧图标的我来说,一下子适应不过来,老觉得好像是640*480分辨率一样,很不爽的感觉。不过很快我就说服自己适应这些硕大的图标了。 

OK,现在赶紧打开Computer,出现了我们最经常使用的My Computer窗口。这个界面对于没用过Vista早期版本(即Longhorn前几个版本)的人来说,绝对是个Surprise!感觉中这类窗口似乎不是Windows窗口,而更像是在Mac,或者X-Window中的窗口。不过左下角Windows图标和Start字样才会让我们回到现实中,这确实是在Windows里。最顶上的后退和前进按钮和一个导航栏加以搜索栏让人瞬间明了目前方位。而此时的File菜单则被下降在标准按钮和导航栏下面,这点是在令人讨厌,尽管你不得不承认把标准按钮和导航栏放在窗口最上方能让用户立刻醒目明白目前自己所在,但是,你也不得不承认,这种挑战用户习惯的行为确实让人很讨厌,至少现在是。接着中间区域还是放着类似CDROM、HardDisk、Folder等常规图标,只是大家可以看到每个HardDisk分区都有一条进度条,让你通过图型方式更加明白目前硬盘的使用状况。而在窗口最下边,还多了一个显示Windows里文件夹、文件等类型对象的各种属性信息,比如创建时间、文件名称、作者等等。最让人拍奇的还是Rating和Keywords两个属性,似乎每个文件你都可以给它添加关键字让搜索引擎更方便查找,也可以给它评价个星级,和大家一起分享下5星级文件的感受。这个想法还是不错的,把原本一个一个冷漠的文件,一下子跟用户互动起来。对于Vista中的IE7.0,个人感觉一般。毕竟一个IE窗口多个Tab页的浏览方式,MyIE已经给过我们;而对于RSS浏览时套用默认样式显示也并非特别新鲜。毕竟在IE6发布后就遭撤的IE开发组,在面对RSS等新潮流后又慌忙组建,其应付的成分还是居多的。

接着看看控制面板Control Panel。控制面板改动也不大,就是增加了几个控制选项,和重新划分了控制类别。对于其中的网络功能,这里不得不再抱怨下。我用的是笔记本安装这个Vista的,通过安装以太网卡和无线网卡驱动也顺利识别了这两个网卡。于是接着自然就是为以太网卡分配一个IP地址和输入网关等信息,以让电脑能通过局域网访问Internet。不幸的问题就是,每次重设IP地址,按确定后都要重新启动操作系统才能正常使用这些新的IP地址,也才能顺利访问Internet。这种现象让人感觉一下子回到了解放前,回到了Windows98,令人费解。另外,对于能跑到WindowsXP的大部分应用程序,都可以在Vista上正常运行。而有部分应用程序就不能正常运行,比如我想用Vista玩《泡泡堂》时,就出现启动泡泡堂游戏程序时出错的现象。

总的来说,这些表层上使用感受,真正带给用户的便利的不是很多。因此,我想对于未来Vista发布后,要说服普通家庭用户升级到Vista比较困难,需要给用户一个升级的理由。而对于我们开发人员来说,Vista带给我的惊喜和享受就显得多得多。

Vista离我们还比较遥远,据说是2006年底才正式发布,这还是不包含再次跳票的风险估计。相对于Vista来说,MSN7.5,甚至MSN8.0就离我们稍微近些了。MSN7.5的测试版近期即将正式发布测试,而我们却已经可以通过一些途径获取到MSN7.5的中文或英文测试版了。这次新版的MSN7.5增加了一些小功能,诸如语音剪辑、动态会议背景以及重新设计过的界面及按钮。其中比较突出的是增加了语音剪辑和加强了语音的功能。恰好在MessBase.com上还进一步发现了未来MSN8.0和下一代Hotmail的截图,很是让人期待。让我们一起期待吧。

                

posted on 2005-08-14 19:03:00 by liuhuimiao  评论(47) 阅读(28529)

Powered by: Joycode.MVC引擎 0.5.2.0