2

我正在查看 .NET 紧凑框架的 OpenNETCF SDF BackgroundWorker 实现中的代码,看起来下面的代码不是线程安全的。但是智能设备框架已经存在了很长时间,所以我错过了什么?这是线程安全的吗?如果是,为什么?

请注意,我不倾向于发布整个课程,因为即使 SDF 可以免费使用,但期望客户为 SDF 的许可证付费。如果任何 SDF 团队甚至反对这个教育摘录,那么我会立即提出这个问题。

这是将方法调用出列以在 UI 线程上调用它们的后台线程:

private void ProgressDispatcherProc()
{
    this.m_stopThreads = false;
    while (!this.m_stopThreads)
    {
        while (this.m_progressQueue.Count > 0)
        {
            MethodInvoker method = null;
            ProgressChangedEventArgs args = this.m_progressQueue.Dequeue();
            if (this.ProgressChanged != null)
            {
                if (method == null)
                {
                    method = () => this.ProgressChanged(this, args);
                }
                this.m_guiMarshaller.BeginInvoke(method);
                Application.DoEvents();
            }
        }
        Thread.Sleep(this.WorkerReportsProgress ? 5 : 0x3e8);
    }
}

该变量m_progressQueue是标准 System.Collections.Generic.Queue<>。

我担心的是没有锁定来保护队列,它在一个线程中排队并在这个线程中出队。我假设在一个简单的布尔值上循环while (!this.m_stopThreads)是足够安全的,因为据我了解,在 .NET Compact Framework 中,所有变量访问都被视为 volatile。

4

1 回答 1

2

我同意它应该有一个锁,至少在Dequeue调用周围,像这样:

lock(m_progressQueue.SyncRoot)
{
    ProgressChangedEventArgs args = this.m_progressQueue.Dequeue(); 
}

它可能会在课堂的其余部分使用它们。

于 2012-09-07T13:31:36.237 回答