时间:2011-01-06 19:21:48

标签: c# thread-safety extension-methods

2 个答案:

答案 0 :(得分:9)

答案 1 :(得分:7)

这两个版本都不是线程安全的,具体取决于“线程安全”的含义。考虑你的第二个版本:

   var h = handler;          
   if (h!= null) 
       h(sender, args);

“handler”是某个字段的副本,其中包含一个不可变委托。假设在null检查之后,该字段在另一个线程上变为“null”。在这种情况下,您的代码不会崩溃,因为您已经复制了原始的非null值。但仅仅没有崩溃不会使程序线程安全。一个不会崩溃但仍会产生错误结果的程序仍然不是线程安全的。

假设当另一个线程将事件字段设置为null时,它还会改变某些状态,即先前的内容需要正确运行。您现在将运行一个事件处理程序,该处理程序依赖于在另一个线程上突变的状态;你正在运行一个过时的事件处理程序。

没有简单的方法可以防止这个问题;如果那是你所处的情况,那么你将不得不非常仔细地设计你的线程逻辑,以便处理这种情况。