避免在C#中重复的事件订阅

您如何建议避免重复事件订阅的最佳方法? 如果这行代码在两个地方执行,则事件将运行两次。 我试图避免第三方事件订阅两次。

theOBject.TheEvent += RunMyCode; 

在我的委托制定者中,我可以有效地运行这个……

 theOBject.TheEvent -= RunMyCode; theOBject.TheEvent += RunMyCode; 

但这是最好的方法吗?

我认为,最有效的方法是使您的事件成为属性并为其添加并发锁,如下例所示

 private EventHandler _theEvent; private object _eventLock = new object(); public event EventHandler TheEvent { add { lock (_eventLock) { _theEvent -= value; _theEvent += value; } } remove { lock (_eventLock) { _theEvent -= value; } } } 

我之前做过这个….它假设最后一个订阅者被调用是可以接受的。

 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); } } } } 

你的代码是multithreading的吗? 只有在multithreading时才需要并发锁。 如果不是它的开销。

因此,您取消订阅和订阅的方法是正确的。

谢谢

如果您拥有该对象类的源,则可以访问TheEvent的InvocationList。 您可以为事件实现自己的添加访问器,并在添加之前进行检查。

但是,我认为你的方法也很好。

我使用你的方法除了一个细节。 我认为,当您创建订阅者或对象的新实例时,应该订阅事件,这使代码更加直接。 因此,您需要的只是在正确的物体处理后仔细观察(配置图案是方便的解决方案)。

您提到您使用第三方事件,这意味着您无法提供自己的添加/删除方法实现,因为您已被建议。 但是在您自己的类中使用自己的事件,您应该定义自己的事件添加/删除方法的实现,以解决您的问题。