2

C# (4.0) に通常の Queue オブジェクトがあり、この Queue にアクセスする BackgroundWorkers を使用しています。

私が使用していたコードは次のとおりです。

   do
    {
        while (dataQueue.Peek() == null // nothing waiting yet 
            && isBeingLoaded == true // and worker 1 still actively adding stuff
        )
            System.Threading.Thread.Sleep(100);

        // otherwise ready to do something: 
        if (dataQueue.Peek() != null) // because maybe the queue is complete and also empty 
        {
            string companyId = dataQueue.Dequeue();
            processLists(companyId);
            // use up the stuff here //
        } // otherwise nothing was there yet, it will resolve on the next loop.
    } while (isBeingLoaded == true // still have stuff coming at us 
           || dataQueue.Peek() != null);   // still have stuff we haven’t done

ただし、スレッドを扱うときは . を使用する必要があると思いConcurrentQueueます。ConcurrentQueue上記のように Do While ループで a を使用する方法の例があるかどうか疑問に思っていましたか?

TryPeek で試したことはすべてうまくいきませんでした..

何か案は?

4

1 に答える 1

5

BlockingCollection<T>をプロデューサー/コンシューマー キューとして使用できます。

私の答えはあなたのアーキテクチャについていくつかの仮定をしていますが、おそらくあなたが適切だと思うようにそれを形作ることができます:

public void Producer(BlockingCollection<string> ids)
{
    // assuming this.CompanyRepository exists
    foreach (var id in this.CompanyRepository.GetIds())
    {
        ids.Add(id);
    }

    ids.CompleteAdding(); // nothing left for our workers
}

public void Consumer(BlockingCollection<string> ids)
{
    while (true)
    {
       string id = null;
       try
       {
           id = ids.Take();
       } catch (InvalidOperationException) {
       }

       if (id == null) break;

       processLists(id);
    }
}

必要な数のコンシューマーを起動できます。

var companyIds = new BlockingCollection<string>();
Producer(companyIds);

Action process = () => Consumer(companyIds);

// 2 workers
Parallel.Invoke(process, process);
于 2013-02-20T22:34:26.713 に答える