2012-08-17 47 views
2

伪代码:C#事件:哪个线程

class A 
{ 
    Dictionary<string, object> dic = new Dictionary<string, object>(); 
    public Do() 
    { 
     some_a.SomeEvent += (s, e) => 
       { 
        dic["some_string"] = new object(); 
       }; 
     dic["some_other_string"] = new object(); 
    } 
} 

这安全吗?这将是如果两个字典操作都在同一个线程上。他们呢?

编辑在我的情况下,事件被触发在与Do相同的线程,所以它是安全的。

+0

好吧,它取决于你的“some_a”对象调用SomeEvent处理程序的线程。如果是的话,假设它是安全的,否则,不。 – 2012-08-17 10:38:34

+0

您可以使用类似于 的东西来检测您正在运行哪个线程Console.Write(System.Threading.Thread.CurrentThread.ManagedThreadId); – AlSki 2012-08-17 10:41:00

回答

4

的事件发生(通常),该调用事件的线程上。所以我们不能实际评论,因为你没有显示导致事件被调用的代码!

严格地说,该事件可能在任何线程 - 要么是因为随机线程调用OnSomeEvent(或任何触发),或者如果OnSomeEvent实现选择使用BeginInvoke出于某种原因,但这种可能性不大。

最终归结为:是否有理由认为此代码中涉及多个线程。

不过:什么绝对并非如此:没有,没有什么会使该事件,订阅它的线程上自动发生。事件订阅只是一个对象+方法对;订阅中不提供任何线索。

1

除非您专门在不同的线程中启动事件处理程序,否则这两个操作确实会在同一个线程上运行(假设单个线程应用程序)。

3

事件处理程序中的代码将在引发事件的线程上执行。

class AsyncWorker 
{ 
    public void BeginWork() 
    { 
     new TaskFactory().StartNew(() => RaiseMyEvent()); 
    } 

    public event EventHandler MyEvent; 

    private void RaiseMyEvent() 
    { 
     var myEvent = MyEvent; 
     if(myEvent != null) 
      myEvent(EventArgs.Empty); 
    } 
} 

var worker = new AsyncWorker(); 
worker.MyEvent += (s, e) => 
        { 
         /* I will be executed on the thread 
         started by the TaskFactory */ 
        }; 
worker.BeginWork();