您如何建议避免重复事件订阅的最佳方法?如果这行代码在两个地方执行,则事件将运行两次。我试图避免第三方事件订阅两次。
theOBject.TheEvent += RunMyCode;
在我的委托制定者中,我可以有效地运行这个......
theOBject.TheEvent -= RunMyCode;
theOBject.TheEvent += RunMyCode;
但这是最好的方法吗?
答案 0 :(得分:20)
我认为,最有效的方法是使您的事件成为属性并为其添加并发锁定,如 Example :
private EventHandler _theEvent;
private object _eventLock = new object();
public event EventHandler TheEvent
{
add
{
lock (_eventLock)
{
_theEvent -= value;
_theEvent += value;
}
}
remove
{
lock (_eventLock)
{
_theEvent -= value;
}
}
}
答案 1 :(得分:5)
我之前已经这样做了......它假设最后一个订阅者被调用是可以接受的。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
MyObject my = new MyObject();
my.Changed += new EventHandler(my_Changed);
my.Changed += new EventHandler(my_Changed1);
my.Update();
Console.ReadLine();
}
static void my_Changed(object sender, EventArgs e)
{
Console.WriteLine("Hello");
}
static void my_Changed1(object sender, EventArgs e)
{
Console.WriteLine("Hello1");
}
}
public class MyObject
{
public MyObject()
{
}
private EventHandler ChangedEventHandler;
public event EventHandler Changed
{
add
{
ChangedEventHandler = value;
}
remove
{
ChangedEventHandler -= value;
}
}
public void Update()
{
OnChanged();
}
private void OnChanged()
{
if (ChangedEventHandler != null)
{
ChangedEventHandler(this, null);
}
}
}
}
答案 2 :(得分:2)
您的代码是多线程的吗?只有在多线程时才需要并发锁。如果不是它的开销。
因此,您取消订阅和订阅的方法是正确的。
由于
答案 3 :(得分:1)
如果您拥有theObject类的源,那么您可以访问TheEvent的InvocationList。您可以为事件实现自己的添加访问者,并在添加之前进行检查。
但是,我认为你的方法也很好。
答案 4 :(得分:0)
我使用你的方法除了一个细节。我认为,当您创建订阅者或对象的新实例时,应该订阅事件,这使代码更加直接。因此,您需要的只是在正确的物体处理后仔细观察(配置彭定康是方便的解决方案)。
您提到您使用第三方事件,这意味着您无法提供自己的添加/删除方法实现,因为您已被建议。但是在您自己的类中,您应该定义自己的事件添加/删除方法,以解决您的问题。