【问题标题】:Programmatically unsubscribe from event以编程方式退订事件
【发布时间】:2012-09-03 12:25:22
【问题描述】:

我有一个使用 COM 对象(COM 公开的 C# 对象)的 vb6 应用程序。 vb6 应用程序正在订阅由 COM (C#) 对象发布的事件。

我的问题是我不知道如何以编程方式取消订阅该事件。我知道如何取消订阅的唯一方法是首先不订阅(即在 vb6 代码中注释掉事件处理程序)。

有没有办法在运行时(以编程方式)取消订阅?也许通过识别与 vb6 事件处理程序对应的委托而不调用它来在 C# 端做一些事情?

提前致谢。

【问题讨论】:

    标签: c# vb6 com-interop


    【解决方案1】:

    您可以通过保留两个对象引用变量来停止在 VB6 中接收事件,一个带有 WithEvents 关键字,一个没有。如果要订阅,请将第一个设置为与第二个相同的对象,如果要取消订阅,请将第一个设置为 Nothing。当你想释放对象时,你需要确保释放/替换它们。

    Dim MyObject As MyClass
    Dim WithEvents MyObjectEvents As MyClass
    
    Public Sub MyObjectEvents_EventName()
      MsgBox "Received event"
    End Sub
    
    Private Sub Subscribe()
      Set MyObjectEvents = MyObject
    End Sub
    
    Private Sub Unsubscribe()
      Set MyObjectEvents = Nothing
    End Sub
    

    【讨论】:

    • 或者,只接收事件并立即返回。
    • 这个替代方案(立即返回)对我来说不可行,因为我试图摆脱的是本地/托管转换,这让我在性能方面感到非常沮丧。没有另一个想法,我可能会在上面尝试您的解决方案。谢谢。
    • 您还可以有一个名为“SendMeEventX”的变量,在引发事件之前检查它。不过,这将影响所有听众。
    • 在 C# 方面,我可以通过在事件上调用 GetInvocationList 来获取在引发事件时将调用的委托列表。如果我可以识别与 vb6 应用订阅对应的委托,那么我就不能在调用其他委托的同时调用该特定委托。
    【解决方案2】:

    另一个让您拥有更多控制权的选项是回调接口。

    您在 .NET 库中公开了一个具有单个 EventXYZ 方法的接口。 您的 VB6 类(和其他侦听器)可以实现此接口并将对该对象的引用传递给您的 .NET 类,以便它引发方法。

    这与 COM 和 .NET 事件在内部使用的方法基本相同,但 .NET 对事件级别的粒度更细。

    【讨论】:

      猜你喜欢
      • 2021-04-17
      • 2021-04-12
      • 1970-01-01
      • 1970-01-01
      • 2018-02-26
      • 2019-11-13
      • 2016-01-02
      • 1970-01-01
      • 2010-11-16
      相关资源
      最近更新 更多