动态附加/分离事件处理程序是否有优势?
手动分离处理程序是否有助于确保不存在对已释放对象的引用?
发布于 2008-09-11 21:04:42
这不是使用AddHandler还是使用Handle的问题。
如果您担心对事件处理程序的引用会干扰垃圾回收,则无论处理程序是如何附加的,都应该使用RemoveHandler。在窗体或控件的Dispose方法中,移除所有处理程序。
我曾经在Windows Forms应用程序(Windows1.1天)中遇到过这样的情况:在没有其他引用的控件上调用事件处理程序(无论从哪个角度来看,这些控件都是死的,我本以为是GC的) --调试起来非常困难。
我会使用RemoveHandler去掉你不打算重用的控件上的处理程序。
发布于 2008-09-11 20:53:24
我非常确定Handles子句只是语法糖,它将一条AddHandler语句插入到您的构造函数中。我使用这段代码进行了测试,并禁用了应用程序框架,这样构造函数就不会有额外的东西:
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 ClassIL最终是这样的:
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周围的两个相同的代码块。我认为这只是句法上的糖。
发布于 2013-10-11 05:15:27
将字段声明为WithEvents将导致编译器自动生成具有该名称的属性。getter返回支持字段的值。setter稍微复杂一点。它首先检查支持字段是否已经具有正确的值。如果是这样,它就会退出。否则,如果支持字段为非空,它会向支持字段所标识的对象发出所有事件的"RemoveHandler“请求。接下来,不管支持字段是否是非空的,它都会将其设置为等于请求的值。最后,如果新值为非空,则无论旧值是否是非空的,属性都会向新值标识的对象发出所有事件的"AddHandler“请求。
如果在放弃对象之前将对象的所有WithEvents成员都设置为Nothing,并避免在多线程中操作WithEvents成员,则自动生成的事件代码不会泄漏。
https://stackoverflow.com/questions/57567
复制相似问题