RunWorkerCompleted处理程序中的线程安全性

时间:2013-07-30 08:52:14

标签: c# backgroundworker

我无法弄清楚使用RunWorkerCompletedHandler s的线程安全问题。我在Stack Overflow上的其他地方找到了这个:

  

如果在UI线程上创建了BackgroundWorker,DoWork将在线程池线程上运行,RunWorkerCompleted将在UI线程上运行。

     

如果在后台线程(即不是UI线程)上创建BackgroundWorker,DoWork仍将在线程池线程上运行,RunWorkerCompleted也将在线程池线程上运行。

鉴于以下课程:

class TestingClass
{
    private BackgroundWorker _bgWorker = new BackgroundWorker();
    private int _counter = 0;

    private readonly int _creatorID;

    public TestingClass()
    {
        _creatorID = Environment.CurrentManagedThreadId;

        _bgWorker.DoWork += DoAsyncWork;
        _bgWorker.RunWorkerCompleted += CompleteAsyncWork;
        _bgWorker.RunWorkerAsync();
    }

    public void IncrementCounter()
    {
        // We only allow the creator of this instance to call this function
        // because instances of this class will not be shared with other threads.
        Debug.Assert(_creatorID == Environment.CurrentManagedThreadId);

        ++_counter;
    }

    private void DoAsyncWork(object sender, DoWorkEventArgs e)
    {
        int i = 0;
        while (i < 100000)
            ++i;
    }

    private void CompleteAsyncWork(object sender, RunWorkerCompletedEventArgs e)
    {
        // Apparently _creatorID == Environment.CurrentManagedThreadId isn't guaranteed here!

        // Modification of member variable after the asynchronous part
        // has been completed.
        ++_counter;
    }
}

由于CompleteAsyncWork不一定会在创建实例的线程上运行,我假设创建线程有可能在执行IncrementCounter时调用CompleteAsyncWork 。在这种情况下修改RunWorkerCompletedHandler中的成员变量是否安全?如果不是,那么正确的方法是什么?

1 个答案:

答案 0 :(得分:2)

  

如果不是,那么正确的方法是什么?

正确的方法是仅在主GUI线程上创建BGW。它们在任何其他方面都没有多大用处。