我的项目中有一种情况,我连接到多个服务器并监听事件。每当从服务器接收到事件时,Handler 就应该将该事件添加到公共队列中进行处理。所有连接都应将接收到的事件添加到队列中。
foreach(var item in collection)
{
Connection c = new connection(item);
c.start();
c.EventReceived+=new EventHandler(myHandler);
list.add(c);
}
protected void myHandler(eventArgs)
{
//add it to the concurrent queue
}
在这里我怀疑它是否能够在没有任何线程问题的情况下处理这些事件。如果您有任何模式或内置 API 可以安全地处理此问题,请告诉我。
线程安全总是需要一个上下文 - a从何而来.
如果你的意思是+=
For the +=
,这取决于事件的实现方式。如果它被实现为类似字段的事件,即
public event SomeEventType EventReceived;
那么是的:它是线程安全的。该规范要求类似字段事件的访问器是线程安全的,尽管实现可能有所不同(例如,MS 编译器过去使用lock(this)
or lock(typeof(DeclaringType))
,但是它现在使用Interlocked
反而)。
如果该事件是手动实现的,即
public event SomeEventType EventReceived {
add { ... }
remove { ... }
}
那么线程安全性完全由add
/remove
实施。
如果你的意思是调用
那么这是线程安全的,因为委托是不可变的,但请注意,这一切都发生在调用该线程的单个线程上。然而,一个常见的错误是在null
test:
if(EventReceived != null) EventReceived(this, someArgs);
以上是not线程安全,因为从技术上讲,EventReceived
测试后可以改变。为了确保这不会出错,应该是:
var handler = EventReceived;
if(handler != null) handler(this, someArgs);
如果你指的是处理程序
然后线程安全性完全由各个处理程序定义。例如,在 UI 应用程序中,处理程序必须检查并切换到 UI 线程。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)