带有空检查的事件调度的多线程安全
在基于事件的编程中,事件允许不同的对象进行通信并对某些事件做出反应。在事件处理程序委托上使用空检查来分派事件是一种常见的做法,如下所示:
public event EventHandler SomeEvent; ... { .... if(SomeEvent!=null)SomeEvent(); }
但是,在多线程环境中,存在潜在的竞争条件,其中另一个线程可以修改事件的调用列表在空检查和调用之间。这可能会导致异常或不正确的行为。
解决多线程问题
为了缓解这种情况,建议将事件处理程序委托分配给事件中的局部变量调度方法,如下所示:
protected virtual void OnSomeEvent(EventArgs args) { EventHandler ev = SomeEvent; if (ev != null) ev(this, args); }
通过这样做,任何后续对 SomeEvent 事件处理程序列表的修改都不会影响存储在 ev 变量中的副本。这确保了即使事件处理程序列表同时发生变化,事件也会被正确调用。
需要注意的是,该解决方案仅解决多线程事件处理的一个方面。它没有完全考虑已失效的事件处理程序或在复制后订阅的事件处理程序。有关该领域最佳实践的综合指南,请参阅 Eric Lippert 的博客文章和 StackOverflow 上有关该主题的讨论。
以上是空检查派发事件时如何保证多线程安全?的详细内容。更多信息请关注PHP中文网其他相关文章!