2

.NET コンパクト フレームワークの OpenNETCF SDF BackgroundWorker 実装内のコードを見ていましたが、次のコードはスレッド セーフではないようです。しかし、スマート デバイス フレームワークは何年も前から存在しています。これはスレッドセーフですか?もしそうなら、なぜですか?

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 では、すべての変数アクセスが揮発性として扱われるため、単純なブール値のループは十分に安全であると思います。

4

1 に答える 1

2

少なくともDequeue呼び出しの周りで、次のようなロックが必要であることに同意します。

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

そして、おそらくクラスの残りの部分でそれらを使用できます。

于 2012-09-07T13:31:36.237 に答える