4

次のコードでは、この例で 2 つのスレッドを使用して適切なリソースを共有しています。プログラムが正常に動作しているように見えるため、queue使用する必要がありますlocken-queueing or dequeuing

class Program
{   
    static Queue<string> sQ = new Queue<string>();

    static void Main(string[] args)
    {
        Thread prodThread = new Thread(ProduceData);
        Thread consumeThread = new Thread(ConsumeData);
        prodThread.Start();
        consumeThread.Start();
        Console.ReadLine();
    }

    private static void ProduceData()
    {
        for (int i = 0; i < 100; i++)
        {
            sQ.Enqueue(i.ToString());               
        }
    }

    private static void ConsumeData()
    {
        while (true)
        {
            if (sQ.Count > 0)
            {
                string s = sQ.Dequeue();
                Console.WriteLine("DEQUEUE::::" + s);
            }
        }
    }
}
4

1 に答える 1

8

はいSystem.Collections.Generic.Queue<T>、同時に書き込みと読み取りを行うにはスレッドセーフではありません。エンキューまたはデキューする前に同じオブジェクトをロックする必要があるか、.NET 4/4.5 を使用している場合は、System.Collections.Concurrent.ConcurrentQueue<T>代わりにクラスを使用してTryDequeueメソッドを使用します。

現在の実装がこれまでのところ問題を引き起こしていない理由は、Thread.Sleep(500)呼び出し (本番コードで使用する必要があるものではない) によるものです。つまり、読み取り操作以降、読み取りprodThread中にキューに書き込みません。consumeThread500ms未満かかります。オッズを削除するThread.Sleepと、ある時点で例外がスローされます。

于 2012-12-21T23:40:33.923 に答える