我无法弄清楚使用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
?如果不是,正确的方法是什么?