假设我有一个事件表明收到了一些数据:
public event<DataEventArgs> EventHandler SomeDataReceived;
protected virtual void OnSomeDataReceived(DataEventArgs e)
{
EventHandler handler = SomeDataReceived;
if (handler != null)
{
handler(this, e);
}
}
我有一个处理它的事件处理程序:
private void m_SomeDataReceived(object sender, DataEventArgs e)
{
... //handling received data
}
现在假设有些设备随机发送数据消息。有一次我在执行m_SomeDataReceived委托代码时收到一条消息。我的意思是当事件几乎同时发生时处理会发生什么?在这种情况下处理程序是并行执行还是在另一个执行之前必须等待?
答案 0 :(得分:2)
是和否。如果事件发生在同一个线程上,则一个接一个地运行,但是如果每个设备都在自己的线程上运行,事件处理程序也可以在并行执行。
事件与普通方法没有什么不同。如果你想做shure他们不是在paralell执行使用锁定:
private void m_SomeDataReceived(object sender, DataEventArgs e)
{
lock (SyncRoot)
{
... //handling received data
}
}
或者将它们放在同一个线程上:
protected virtual void OnSomeDataReceived(DataEventArgs e)
{
EventHandler handler = SomeDataReceived;
if (handler != null)
{
CONTEXT.Invoke(() => handler(this, e)); // context can e.g. be a Dispatcher from a WPF control
}
}
在这种情况下,如果处理放弃线程(例如Application.DoEvents()
或await Task.Delay()
),它仍然可以在第一个调用完成之前启动第二个调用!
如果事件是在同一个线程中生成的,并且您希望它们以并行方式执行,则可以执行以下操作:
public static void RaiseAsync<T>(this EventHandler<EventArgs<T>> theEvent, object sender, T args)
{
if (theEvent != null)
{
var eventArgs = new EventArgs<T>(args);
foreach (EventHandler<EventArgs<T>> action in theEvent.GetInvocationList())
action.BeginInvoke(sender, eventArgs, null, null);
}
}
然后,您只需拨打OnSomeDataReceived
。
SomeDataReceived.RaiseAsync(this, args)