2

伪代码:

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,所以它是安全的。

4

3 回答 3

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();
于 2012-08-17T10:39:11.577 回答
3

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

严格来说,事件可能在任何线程上——要么是因为随机线程正在调用OnSomeEvent(或触发器是什么),要么是由于某种原因OnSomeEvent实现选择使用BeginInvoke,但这不太可能。

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

但是:绝对不是这种情况:不,没有什么可以使该事件在订阅它的线程上自动发生。事件订阅只是一个对象+方法对;订阅中没有指定线程。

于 2012-08-17T10:39:14.503 回答
1

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

于 2012-08-17T10:39:05.273 回答