0

我无法弄清楚使用RunWorkerCompletedHandlers 的线程安全含义。我在 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?如果不是,正确的方法是什么?

4

1 回答 1

2

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

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

于 2013-07-30T08:59:58.530 回答