首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Handles与AddHandler

Handles与AddHandler
EN

Stack Overflow用户
提问于 2008-09-11 20:40:57
回答 7查看 3.5K关注 0票数 1

动态附加/分离事件处理程序是否有优势?

手动分离处理程序是否有助于确保不存在对已释放对象的引用?

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2008-09-11 21:04:42

这不是使用AddHandler还是使用Handle的问题。

如果您担心对事件处理程序的引用会干扰垃圾回收,则无论处理程序是如何附加的,都应该使用RemoveHandler。在窗体或控件的Dispose方法中,移除所有处理程序。

我曾经在Windows Forms应用程序(Windows1.1天)中遇到过这样的情况:在没有其他引用的控件上调用事件处理程序(无论从哪个角度来看,这些控件都是死的,我本以为是GC的) --调试起来非常困难。

我会使用RemoveHandler去掉你不打算重用的控件上的处理程序。

票数 2
EN

Stack Overflow用户

发布于 2008-09-11 20:53:24

我非常确定Handles子句只是语法糖,它将一条AddHandler语句插入到您的构造函数中。我使用这段代码进行了测试,并禁用了应用程序框架,这样构造函数就不会有额外的东西:

代码语言:javascript
复制
Public Class Form1

    Public Sub New()
        ' This call is required by the Windows Form Designer. '
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call. '
        AddHandler Me.Load, AddressOf Form1_Load
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim breakpoint As Integer = 4
    End Sub
End Class

IL最终是这样的:

代码语言:javascript
复制
  IL_0000:  nop
  IL_0001:  ldarg.0
  IL_0002:  call       instance void [System.Windows.Forms]System.Windows.Forms.Form::.ctor()
  IL_0007:  nop
  IL_0008:  ldarg.0
  IL_0009:  ldarg.0
  IL_000a:  dup
  IL_000b:  ldvirtftn  instance void WindowsApplication1.Form1::Form1_Load(object,
                                                                           class [mscorlib]System.EventArgs)
  IL_0011:  newobj     instance void [mscorlib]System.EventHandler::.ctor(object,
                                                                          native int)
  IL_0016:  call       instance void [System.Windows.Forms]System.Windows.Forms.Form::add_Load(class [mscorlib]System.EventHandler)

 '... lots of lines here '

  IL_0047:  ldarg.0
  IL_0048:  callvirt   instance void WindowsApplication1.Form1::InitializeComponent()
  IL_004d:  nop
  IL_004e:  ldarg.0
  IL_004f:  ldarg.0
  IL_0050:  dup
  IL_0051:  ldvirtftn  instance void WindowsApplication1.Form1::Form1_Load(object,
                                                                           class [mscorlib]System.EventArgs)
  IL_0057:  newobj     instance void [mscorlib]System.EventHandler::.ctor(object,
                                                                          native int)
  IL_005c:  callvirt   instance void [System.Windows.Forms]System.Windows.Forms.Form::add_Load(class [mscorlib]System.EventHandler)
  IL_0061:  nop
  IL_0062:  nop
  IL_0063:  ret
} // end of method Form1::.ctor

注意IL_000b和IL_0051周围的两个相同的代码块。我认为这只是句法上的糖。

票数 3
EN

Stack Overflow用户

发布于 2013-10-11 05:15:27

将字段声明为WithEvents将导致编译器自动生成具有该名称的属性。getter返回支持字段的值。setter稍微复杂一点。它首先检查支持字段是否已经具有正确的值。如果是这样,它就会退出。否则,如果支持字段为非空,它会向支持字段所标识的对象发出所有事件的"RemoveHandler“请求。接下来,不管支持字段是否是非空的,它都会将其设置为等于请求的值。最后,如果新值为非空,则无论旧值是否是非空的,属性都会向新值标识的对象发出所有事件的"AddHandler“请求。

如果在放弃对象之前将对象的所有WithEvents成员都设置为Nothing,并避免在多线程中操作WithEvents成员,则自动生成的事件代码不会泄漏。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57567

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档