我有一个对象列表,我想为每个对象订阅/取消订阅一个事件(通过委托,因为我需要将额外的参数传递给方法)。 所以我有这样的东西:
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的引用?
答案 0 :(得分:-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
}
更新我刚刚看到您需要使用委托来添加其他参数
您可以使用局部函数来捕获父方法的属性,但是在您的情况下,您将需要捕获循环变量。那是行不通的,所以我试图找到一种方法将mh
从sender
中删除,因为它似乎是相关的。是sender
和monitoredItem
的父项,并且您想将其与lambda(monitorHandler
)一起传递吗?