BackgroundWorker和实例变量

Ala*_*tts 3 .net c#

总是让我感到困惑的一件事是BackgroundWorker似乎如何对周围类的实例变量进行线程安全访问.

鉴于基本课程:

public class BackgroundProcessor
{
    public List<int> Items { get; private set; }

    public BackgroundProcessor(IEnumerable<int> items)
    {
        Items = new List<int>(items);
    }

    public void DoWork()
    {
        BackgroundWorker worker = new BackgroundWorker();
        worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
        worker.DoWork += new DoWorkEventHandler(worker_DoWork);
        worker.RunWorkerAsync();
    }

    void worker_DoWork(object sender, DoWorkEventArgs e)
    {
        var processor = new ProcessingClass();

        processor.Process(this.Items); //Accessing the instance variable
    }

    void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        //Stuff goes here
    }
}
Run Code Online (Sandbox Code Playgroud)

我错误地认为呼叫processor.Process(this.Points);是一个线程安全的呼叫?我怎么不得到跨线程访问冲突?

我确信这很明显,但它总是让我困惑.

sir*_*ide 6

它不是线程安全的,只是看起来那样.您只能获得GUI控件的跨线程异常.很难要求只能从创建GUI控件的线程访问GUI控件.因此框架花时间检查来自其他线程的调用.请注意,这实际上与同步问题正交(至少从我们的角度来看,而不是从USER子系统的角度来看),因为您仍然可以使用锁来防止多个线程同时访问控件并仍然获得跨线程违规.

由于成员变量不是GUI控件,因此不检查跨线程调用,也不检查竞争条件.你必须自己使用锁定或其他机制.除非集合类被破坏,否则不会有异常.我不相信它们是线程安全的,但我不确定这最终意味着什么,我也没有在同时运行的线程之间共享那些变量,所以我实际上没有遇到问题.可以这么说,做正确的事情比希望集合类神奇地工作更好.