VisualStudio.NET技巧5-10

VisualStudio.NET技巧5-10


作者: zdnet  &;nbsp来自:网络


                技巧6. 在ASP.NET中值得注意的两个地方
 
  在ASP.NET中ASPX页面的Page_Load事件有两个让人奇怪的地方,你应该记住它们:
 
  a.有时Page_Load事件在你的ASP.NET页面里会发生多次。这种情况发生的一个可能的原因是你把ASPX页面的AutoEvenWireup值设置成了True。如果是这样,那么在“Sub Page_Load(ByVal Sender as System.Object,ByVal e as System.EventArgs”后面加上“Handles MyBase.Load”这一行就是没有必要的了。既然Visual Studio.NET能够自动的为你处理这个部分,你当然可以将AutoEventWireup值设置成False。
 
  b.有时好象一个按纽的单击事件处理代码并没有运行。这里你应该检查Page_Load事件确保任何加载数据的代码(比方在下拉列表中绑定数据的代码)只在初始加载这个页面的时候运行,而不是在后来客户端数据返回的时候运行。一个检查这种情况的简单的方法是在你的Page_load事件处理函数里添加对Page.IsPostBack值的测试-False意味着这是页面第一次被加载而True则意味着已经发生了一次数据返回过程。
 
 
  技巧7. 将控件数组转换到.NET中来
 
  实现一个控件数组是Visual Basic 6程序员用来削减代码和应用程序复杂性的最常用的方法之一。通用的事件处理函数处理与控件相关的事件。
 
  那些现在使用Visual Basic.NET的程序员发现控件数组(以及类似的东西)已经不再支持了。你还会发现,当你使用转换向导将一个Visual Basic应用程序转换到Visual Basic.NET中来的时候,Visual Basic .NET使用一个兼容的接口来模拟控件数组。但是据说这些兼容的接口不会一直被支持(但是至少下个星期还是支持的)。我想使用“原始”的技术实现“控件数组”更好。
 
  实际上有一种简单的方法让一个事件处理函数来应付许多操作的事件。只需要在事件处理函数里为Handles参数添加额外的事件。下面的例子演示了我如何为TextBox1和TextBox2同时在Handles参数里添加TextChanged事件,但是我怀疑它们只是将这个相同的参数作为源事件类似进行传递。
 
 
  Private Sub TextBox1_TextChanged(ByVal Sender As System.Object,_
  ByVal e As System.EventArgs)_
  Handles TextBox1.TextChanged,TextBox2.TextChanged
 
  下一个问题是分辨出是哪一个TextBox触发了这个事件。在Visual Basic.Net里事件处理函数返回一个叫做“sender”的变量指向触发这个事件的对象。要访问这个对象并察看它的属性,你需要声明一个相应的对象(在这个例子中是TextBox)然后将它定值为Sender。
 
 
  Dim tbSend As TextBox=sender
 
  在这个工作完成以后,你可以容易的访问触发这个事件的控件的属性了。
 
 
  Select Case tbSent.Name
  Case "TextBox1"
  TextBox3.Text="TextBox1 contents:"&;tbSent.Text.ToString
  Case "TExtBox2"
  TextBox3.Text="TextBox2 contents:"&;tbSent.Text.ToString
  EndSelect
  End Sube
 
  不幸地的是,以前在“经典”的Visual Basic中被传递的Index属性已经不存在了。因为Index属性不再需要是什么特别的数字(只需要是一个唯一的整型),我使用它来传值,这样我的事件处理函数就能够简单的把它作为一个数据值使用。
 
  例如,当我想要演示不同的ADO LockType 属性的使用方法的时候,我可以创建一套CheckBox控件并把它们的Index属性设置成不同的LockType 枚举类型。当CheckBox Change事件发生的时候,我可以简单的把Index值赋给Recordset LockType属性。
 
  另一种替代的方法是,你可能会想用Tag属性来传递特定控件的值或者简单的设置Name属性的值使得这个额外的值能够被引用。能够让我们的Index属性重新出现是很好的--但是我也并不是很迫切的需要这样做。
 
  另一个技巧:当你在创建应用程序的时候你可能会删除一个表单中的控件而且希望这些代码仍然被保留。事实上这些代码(至少大部分代码)是被保留的。在Visual Basic.Net中,当你从表单中删除或者剪切一个控件的时候,为这个控件编写的事件处理代码已经改变;Visual Basic.NET提取出Handles 关键字以及参数并把它们废除。当你粘贴进你的新控件的时候你会发现Visual Basic.NET会创建一个新的事件处理函数--一个带有Handles关键字而另一些则没有。我使用一个注释符来保留Handles语句来确保这些代码不会造成麻烦。用这种方法我能够把它拷贝回我以前的事件处理函数里去。
 
 
  技巧8. 在工具栏里保存经常使用的代码
 
  新的Visual Basic.NET IDE最酷的功能之一就是它能够在工具栏里保存代码片段。这个功能真的很容易使用。你只需要在编码窗口里选择一段你想要重复使用的代码(我保存的是应用程序中的Dim语句和ConnectionString语句),然后简单的把它拖动到工具栏上。一旦它到了工具栏上,你想要再次使用它就很容易了;只需要把它拖动到编码窗口里然后放开它。这些语句能够保存并在项目之间进行共享,所以你能够容易的把已经写好的代码加入到应用程序中来。
 
  技巧9. 选择合适的数据访问工具
 
  我想我们将在未来的几年里就什么是最好的数据访问接口而讨论一番。因为ADO.NET并不支持基于COM的ADO(我把它叫做ADOc)支持的所有功能,开发者们不得不作出一个重大的选择。我过去的九个月里就在写一本叫做“ADO.NET和ADO例程及最佳数据库访问方式(Apress出版社)”的书,在这本书中我将帮助开发者们作出这个选择。
 
  目前开发者们能够使用ADOc并获得对服务端的乐观算法或者悲观算法实现的游标以及静态的,基于关键字的,动态的或者离线的(批处理优化的)游标实现。在ADO.NET中他们能够选择通过DataSet使用优化的同步访问或者使用底层的(并且更快速的)DataReader来返回一个“实时”的数据流。
 
  使用ADOc的问题是我觉得其性能会有所降低因为每次对非受控代码(unmanaged)MDAC DLL(ADO)的访问将两次经历一个叫做COM Interop的翻译过程--一次是发送请求而另一次是从MDAC返回数据。ADOc方式还依赖于我称之为OSFA(one size fits all一次调用,全部满足)的数据接口,比方OLE DB。
 
  是的,ADO.NET提供了它自己的OSFA OleDb.Net Data Provider,但是它也实现了新的SqlClient 数据提供程序它直接使用TDS。这是从DB-Library(以及VBSQL)出现以来出现的第一个TDS。这个(全新)的数据访问方法将解放开发者访问数据的方式。是的,它只能在SQL Server上工作。但是这并不意味着其它的销售商(或者微软)不会创建其它的“原始”的数据访问接口来获得比OLE DB或者ODBC更好的性能。
 
  假设你能够容忍缺少ADOc诸如keyset 游标和悲观锁定算法这样的功能。那么你是不是就应该使用DataSet或者DataReader来管理你的数据呢?实际上DataSet使用DataReader来进行底层的I/O。DataReader是一个非常简单但是非常快速的接口。它每次提供一行数据。虽然你能够把单个的数据行放到一个数组里,但是你并不会想这么做因为这需要额外的工作和性能上的损失。这意味着你需要每次一行进行遍历而且每一行都是使用特定数据类型的Get语句获得的。
 
  即使是对于所有这些代码,数据提取过程,使用DataReader还是比用来填充由DataSet管理的DataTables的Fill方法要快。之所以这样说是因为DataSet比ADOc Recordset复杂上好几个数量级也更加灵活而且强大。它能够轻易的处理级联数据(不需要特别的Shape语句)并能够无缝的绑定到复杂的控件。它还能够通过由开发者定义的包含了适当的UPDATE,DELETE,和INSERT SQL语句或者存储过程的Command对象来修改数据。
 
  是的,只要还有许多新的,到今天还没有测试过的应用程序来最大化的利用这套新的数据访问技术,那么争论就会继续下去。
 
 
  技巧10. 确保关闭了你的数据库连接
 
  新的.NET 通用语句运行库的一个大的(真正相当大的)不同之处在于它的垃圾内存回收功能。它好象是在上一次纽约市垃圾回收工人所使用的技术上建立起来的。它并不是把对象除去并设置成Nothing,这些无用的对象(比方ADO.NET Connection对象)仅仅是被遗弃在街道上(内存)中腐烂掉。
 
  只有在回收器没有更多的空地(内存)可以用的时候,它才会进行查找,统计出最不常使用的对象然后把它们装进回收袋里。这意味着如果你让一个Connection对象(即一个SqlConnection,OleDbConnection或者OdbcConnection)超出它们的范围存在而不进行关闭的话,这个连接会保持打开的状态并存放在缓冲区里直到“春天”来临。ADO.NET并不保证关闭这些连接。如果你有很多空闲的RAM,这个问题并不会很糟糕,因为CLR垃圾回收程序不会觉得需要进行垃圾回收直到所有可用的内存都已经满了。
 
  这意味着当Connection不再使用的时候,在你打开的Connections上使用Close方法是非常关键的。如果你使用的是一个DataReader对象,你可以要求它自动为你关闭连接,但是除非你关闭DataReader本身的话,这个连接并不会被关闭。如果你不想让你的程序在办公室里变得臭名招著的话,我建议你在打扫自己的垃圾的时候要求更严格一些。
 
 
    (2005-5-17:12:00)

 感谢原创者的辛勤劳动,希望对您有所帮助,转载请注明原出处。
 您可能对 [C#] 的这些文章也感兴趣:

用C#设计Windows应用程序模板  c#语言重点知识详解(四:加框与解框)
C#的多线程机制初探(2)  Windows窗体控件开发示例:扩展TreeView
个性化的分页实例  使用.NETFramework进行事务处理
用C#实现文件下载器(2)  Microsoft.Net
C#锐利体验(7.2)  C#锐利体验(4.1)
关于C#中委托的学习  C#中为DataGrid添加下拉列表框
浅析VisualC#事件处理机制  C#文件操作:上传 下载 删除
C#利用正则表达式实现字符串搜索  ASP.NET追捕休整版
C#锐利体验(1.1)  用C#对Illustrator矢量图形软件进行编程
C#实现web信息抓取  VisualStudio.Net内幕(7)