我有一个系统,其中一类“自动化提供程序”正在与某些Control对象一起使用,以为它们提供一些高级监视功能(通过动态监视事件)。
我的代码的一部分;名为Automation_Provider
的类包含名为Browser_Navigate
的函数,该函数接受对System.Windows.Forms.WebBrowser
实例的引用,并通过URL执行.Navigate
操作。
它提供的特殊功能是将事件处理程序设置为Browser.DocumentCompleted
,以便在引发事件时执行某些操作。
这部分实际上有效。什么是行不通的,是我试图动态删除导致首先调用Subroutine的处理程序,但它似乎并没有删除该处理程序,如果我尝试再次调用该函数,它将触发两次。
代码如下:
Public Class Automation_Functions
Public Function Browser_Navigate(ByRef Browser As WebBrowser, ByVal Address As String) As Function_Status
'-----------------------------------------------------------------------------------
' A bunch of URL checks are performed here to make sure the "Address" is a valid URL
'-----------------------------------------------------------------------------------
AddHandler Browser.DocumentCompleted, AddressOf Browser_Navigation_Callback
Browser.Navigate(Address)
End Function
Private Sub Browser_Navigation_Callback(sender As Object, e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs)
'Get the browser object from the sender and remove the handler that initially called this function
Dim Browser As WebBrowser = CType(sender, WebBrowser)
RemoveHandler Browser.DocumentCompleted, AddressOf Browser_Navigation_Callback
'------------------------------------------------------------------------------------------
' A bunch of operations are performed here related to telling the caller of the original
' function about the performance of the web page - stuff like load time, etc.
'------------------------------------------------------------------------------------------
End Sub
End Class
不过,过去的处理程序从未真正从Browser_Navigation_Callback
函数中删除-我知道这是因为第二次调用Browser_Navigate
函数会导致Browser_Navigation_Callback
函数被称为 两次 ,那么如果您第三次调用它,它会被称为 三次! -处理程序只是彼此叠加因为它们实际上从未被移除。
我一直无法找到发生这种情况的任何原因-我假设它可能与WebBrowser
对象实际上在另一个类中并强制转换{ {1}}作为WebBrowser对象不会将其引用回原始WebBrowser实例,而是创建一个新实例。但是我不知道如何确认这确实是实际发生的情况,因为我在调试模式下看不到附加的事件处理程序。
除此之外-此代码应该可以正常工作。任何帮助将不胜感激!
答案 0 :(得分:0)
未设置Option Strict
时,VB的功能之一是它将使用“轻松委托转换”。这意味着当委托参数与要求的签名不完全匹配但兼容时,VB会自动插入一个匿名包装程序,该包装程序将从提供的委托转换为要求的签名。
这与AddHandler
和RemoveHandler
产生负面互动。 VB在每个调用上创建一个新的匿名包装,并且每个实例都是不同的。实际上,这意味着使用宽松的委托转换时,不可能删除已添加的处理程序。
启用Option Strict
时,将禁用宽松的委托转换,因此当委托参数与所需的签名不完全匹配时,它将变成编译器错误。我还没有找到单独的编译器开关来关闭宽松的委托转换,因此处理此问题的唯一方法是为文件打开Option Strict
。