订阅/取消订阅列表中的事件[重复]

Posted

技术标签:

【中文标题】订阅/取消订阅列表中的事件[重复]【英文标题】:Subscribe/unsubscribe to an event in a list [duplicate] 【发布时间】:2020-11-11 04:11:52 【问题描述】:

我有一个对象列表,我想为每个对象订阅/取消订阅一个事件(通过委托,因为我需要向方法传递额外的参数)。 所以我有这样的事情:

 public void MonitoringCtrl(bool monitoringOn)
    
        foreach (var mh in monHandlers)
        
            evHandler = (sender, e) => OnNotification(sender, e, mh);

            if (monitoringOn)
            
                //subscribe to event
                mh.monitoredItem.Notification += evHandler;
            
            else
            
                //unsubscribe
                mh.monitoredItem.Notification -= evHandler;
            
        

        //do other stuff
    

这在订阅时有效,但在取消订阅时不起作用,大概是因为我在 foreach 中重新声明了 evHandler。如何保存对 evHandler 的引用?

【问题讨论】:

你可以把你的 lambda 变成一个真正的方法。或者将您的 lamda 存储为班级成员。 网站上已经有很多关于这种一般情况的问答。您将无法遵循命名方法方法,因为您依赖于捕获的mh 值。因此,您将不得不使用其中一种替代方法,例如将委托实例保存在某处,或从sender 检索mh 值(例如,如果您有一些从monitoredItemmh 对象的映射持有该参考)。实际上,如果你能做到后者,那么命名方法起作用。 【参考方案1】:

这是因为第二次调用MonitoringCtrl()(当您将false 传递给取消订阅时)会创建一个新的事件处理程序。但该新实例不会取消订阅之前附加的事件处理程序实例。

您无需为循环中的每个元素创建新的事件处理程序,也不得创建新的事件处理程序来取消订阅。您可以为所有事件保留一个事件处理程序作为成员变量。但是通过绑定到这样的方法更容易做到这一点:

public void MonitoringCtrl(bool monitoringOn)

    foreach (var mh in monHandlers)
    
        if (monitoringOn)
        
            //subscribe to event
            mh.monitoredItem.Notification += HandleNotification;
        
        else
        
            //unsubscribe
            mh.monitoredItem.Notification -= HandleNotification;
        
    

    //do other stuff


private void HandleNotification(object sender, EventArgs args)

    //do event stuff

更新我刚刚看到您需要使用委托来获取额外的参数

您可以使用本地函数来捕获父方法的属性,但在您的情况下,您需要捕获循环变量。那是行不通的,所以我会尝试找到一种方法将mhsender 中取出,因为它似乎是相关的。 sendermonitoredItem 并且它是 monitorHandler 的父级,你想通过 lambda (mh) 传递?

【讨论】:

以上是关于订阅/取消订阅列表中的事件[重复]的主要内容,如果未能解决你的问题,请参考以下文章

通过匿名委托取消订阅事件[重复]

取消/订阅 Xamarin 内容视图中的事件

何处取消订阅附属财产中的事件?

从 UWP 中的自定义 ToolTip 和自定义 Flyout 类取消订阅事件

如何取消 Stripe 计划中的所有订阅?

EventBus事件通信框架 ( 取消注册 | 获取事件参数类型 | 根据事件类型获取订阅者 | 移除相关订阅者 )