调用事件处理程序的 [英] Invoke of an EventHandler
问题描述
我有以下事件处理程序:
I have the following EventHandler:
private EventHandler<MyEventArgs> _myEventHandler;
public event EventHandler<MyEventArgs> MyEvent
{
add { _myEventHandler += value; }
remove { _myEventHandler -= value; }
}
有人能解释以下片段之间的差异?结果
片段事件处理(A):
Could somebody explain the difference between the following snippets?
Snippet EventHandler (A):
//Snippet A:
if (_myEventHandler != null)
{
_myEventHandler(new MyEventArgs());
}
片段的BeginInvoke(B):
Snippet BeginInvoke (B):
//Snippet B:
if (_myEventHandler != null)
{
_myEventHandler.BeginInvoke(new MyEventArgs(), ar =>
{
var del = (EventHandler<MyEventArgs>)ar.AsyncState;
del.EndInvoke(ar);
}, _myEventHandler);
}
有关澄清:什么是调用一个事件处理程序只是因为它是之间的区别并使用的BeginInvoke
?
For clarification: What's the difference between invoking an EventHandler "just as it is" and using BeginInvoke
?
推荐答案
的的BeginInvoke
办法是异步的,这意味着它是在不同的线程提高。这可能是危险的,如果人们不指望它,是事件非常罕见的 - 但它可以是有用的。
The BeginInvoke
approach is async, meaning that it is raised on a different thread. This can be dangerous if people don't expect it, and is pretty rare for events - but it can be useful.
另外,还要注意的严格地说的你应该快照事件处理程序的价值 - 这是尤其的真,如果(通过开始*
)你正在处理的线程
Also, note that strictly speaking you should snapshot the event handler value - this is especially true if (via Begin*
) you are dealing with threads.
var tmp = _myEventHandler;
if(tmp != null) {
tmp(sender, args);
}
此外 - 注意,你的事件订阅的本身的是不是线程安全的;再次,这只是事情,如果你正在处理多线程,但内置的现场般的事件的是线程安全的:
Also - note that your event subscription itself is not thread-safe; again, this only matters if you are dealing with multi-threading, but the inbuilt field-like event is thread-safe:
public event EventHandler<MyEventArgs> MyEvent; // <===== done; nothing more
下面回避的问题是:
- 与快照,我们避免了过去用户空检查和调用之间退订的风险(它确实意味着他们可能会得到他们所没有想到的事件,但它意味着我们不'T杀死提高线程)
- 与现场般的事件改变我们避免丢失当两个线程在同一时间做这个订阅/取消订阅 $ b的风险$ b
- with the snapshot, we avoid the risk of the last subscriber unsubscribing between the null-check and the invoke (it does mean they might get an event they didn't expect, but it means we don't kill the raising thread)
- with the field-like event change we avoid the risk of losing subscriptions / unsubscriptions when two threads are doing this at the same time
这篇关于调用事件处理程序的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!