资源大全 | 神秘文化 | 在线翻译 | QQ专区 | 视频教程 | 彩信频道 | 搜索引擎 | BT下载 |  | 网站地图
设为首页
加入收藏
联系站长
您现在的位置: 一百网络 >> 其他编程 >> Delphi编程 >> 文档正文
最近更新
普通文档 Together与Visual.Studi
普通文档 Together与Visual.Studi
普通文档 Together与Visual.Studi
普通文档 Delphi实现在数据库中存
普通文档 Delphi开发多媒体播放音
普通文档 开发工具大比拼之Visual
普通文档 Delphi串口通讯的监听
普通文档 Delphi中远程控制的实现
普通文档 利用Delphi编写Socket通
普通文档 利用Delphi开发网络数据
推荐文章
  • 此栏目下没有推荐文档
  • 探索VB系列中的事件处理的奥秘(3)

    文章作者:佚名 录入时间:2006-6-2 来源:不详
    网站声明:本站的文章除部分特别声明禁止转载的专稿外,可以自由转载.但请务必注明出处和原始作者,文章版权归本网站与文章作者所有。对于被本站转载文章的个人和网站,我们表示深深的谢意。


     研究异常(Exception)行为

       我将很快给你看看从FileSearch3类中选取的代码。每次一个类的实例找到一个文件,实例就引发它的FileFound事件。这一效果导致.NET Framework相继地运行每个事件处理过程。看看下面的代码:

    ’’以下代码来自FileSearch3.vb
    ’’搜索符合的文件名
    Dim afi() As FileInfo = diLocal.GetFiles(Me.FileSpec)For Each fi As FileInfo In afi
    ’’这相当于:
    ’’ FileFoundEventHandler.Invoke(fi)
    RaiseEvent FileFound(fi)
    Next
    alFiles.AddRange(afi)

      这个技术的问题(正如你已经看到的)是:如果一个异常出现在任何一个侦听器中,异常回滚(bubbles back)到事件引发(event-raising)代码,.NET Framework不再调用事件侦听器,而事件处理就慢慢停了下来。

      如果查看一下IL为示例代码所生成的,情况就变得清楚了。图 6 显示了在ILDASM中FileSearch3.Search方法的反汇编。你在类中看到的RaiseEvent语句直到一个FileFoundEventHandler.Invoke方法调用后才会编译。在内部,一旦这个方法已经调用,你的代码将控制权交给委托的执行过程,同时如果一个未处理的异常在调用列表的任何地方发生,这个异常回滚到调用者(这个代码),同时再没有侦听器获得调用。

    4
      这里有一个方案。胜于一再地简单调用RaiseEvent语句,它可能为你而显式地调用每个单独的侦听器。你可以利用Delegate类的成员以解决在多侦听器下的未处理异常问题。

      手工调用每个侦听器

      尽管RaiseEvent机制是方便的(并且也是令人觉得舒服的,如果你使用Visual Basic 6.0的话)它也有它的缺点,正如你所已经看到的。比依赖于RaiseEvent调用事件侦听器更好的是:你可以自己做这个工作。而你获得了一定的灵活性是你放弃使用RaiseEvent时的舒适为代价的。

      如果你想要完全控制事件侦听器的调用而不只是希望事情如你所愿的方法解决,你将需要利用隐式的FileFoundEventHandler委托类型。你通过调用事件委托实例本身的GetInvocationList方法重新获得一个包含所有事件的侦听器的数组。一旦你有这个列表,你就可以独立地调用每个侦听器的Invoke方法,并且捕捉由事件处理程序引发的任何异常。如果任何侦听器引发一个异常,你就能处理它并将程序继续下去。
    FileSearch4类包含其Search方法中的代码如图 7 显示。通过点击示例窗体上的GetInvocationList按钮运行这个代码。正如你将看到的,示例仍然调用引发一个错误的事件侦听器,但是既然这样,代码就不会在第一次侦听器引发错误时停止搜索文件。因为FileSearch4.Search方法包括独立地调用每个侦听器的代码,它也可以为每个调用处理异常。

    ’ From FileSearch4.vb
    Dim ListenerList() As System.Delegate
    Dim Listener As FileFoundEventHandler
    ListenerList = FileFoundEvent.GetInvocationList()
    ’ Search for matching file names.
    Dim afi() As FileInfo = diLocal.GetFiles(Me.FileSpec)

    For Each fi As FileInfo In afi
      For Each Listener In ListenerList
      Try
       Listener.Invoke(fi)
      Catch
       ’ Something goes wrong? Just move on to
       ’ the next event handler.
      End Try
      Next
      alFiles.AddRange(afi)
    Next


      FileSearch4.Search中的新代码采取了以下动作:

      * 声明一个System.Delegate类型的数组以使得代码可以追踪到事件的所有侦听器:

    Dim ListenerList() As System.Delegate
      * 声明一个描述事件的委托类型的实例,以遍历侦听器数组(你应该记得:所有侦听器过程必须有其特定的类型,否则这个代码将不能被编译,这就是委托的工作方法):

    Dim Listener As FileFoundEventHandler
      * 重新获得侦听器列表,调用FileFoundEvent委托的内部GetInvocationList方法:

    ListenerList = FileFoundEvent.GetInvocationList()
      * 找到文件并遍历包含cor-responding FileInfos的数组,正如你前面已经看到的一样:

    Dim afi() As FileInfo = diLocal.GetFiles(Me.FileSpec)

    For Each fi As FileInfo In afi
    ’’ Code removed here...
    Next

      * 每找到一个文件,FileSearch4.Search就遍历事件侦听器的列表并独立地调用每个委托的回调(Invoke)方法。这允许代码捕捉(而且既然这样,就忽略)任何由每个独立地的侦听器引发的异常。

    For Each Listener In ListenerList
    Try
    Listener.Invoke(fi)
    Catch
    ’’ 出了什么错?只是前进到下一个事件处理程序
    End Try
    Next


       这个示例项目既没有声明FileFoundEventHandler类型也没有声明FileFoundEvent变量。Visual Basic .NET编译器在你的代码中发现事件声明时它会创建这些条目。尽管你可以通过自己声明这些对象以去处含糊不清的感觉,但你并不需要这样做,因为Visual Basic .NET编译器将会为你做好这个工作。

       在Visual Basic .NET 2002 and 2003里你不能修改这个基于.NET的应用程序引发它们自己的内部事件的方式。(你可以在Visual Basic 2005中修改这个行为,正如你后面将要看到的)使用先于Visual Basic 2005的版本时,这里有个方法可以确保你不会在你的事件侦听器中引发问题(记住:在任何事件处理程序中一个未处理的异常将导致.NET Framework停止为当前事件调用侦听器)。为了这样做,确保你自己的事件处理不允许回滚。如果你希望通过多个事件过程获得一个单独的事件处理的话,在你的事件过程中处理所有异常以使得你不会打破事件处理程序的链条。

  • 上一篇文档:

  • 下一篇文档:
  •     查找更多“探索VB系列中的事件处理的奥秘(3)”的内容  
    相关连接
  • 将Java程序变成Windows系统服务

  • 浅析Java多线程程序设计机制

  • Java初学者需掌握的30个基本概念(1)

  • JDBC 入门(1)

  • 面向Java程序员的Ajax:构建动态Java程序(1)