2

500.000ish リストを実行する for ループがあります。これらのそれぞれについて、SmartThreadPool ジョブをキューに入れています。

lines.Length以下には500.000ishのアイテムが含まれています。

私の問題は、それらを一度にキューに入れるとメモリの問題が発生することです..だから私はこれを防ぐためのロジックを書きます:

int activeThreads = _smartThreadPool2.ActiveThreads;
if (activeThreads < maxThreads) 
{
    int iia = 0;
    for (int i = 0; i < lines.Length; i++)
    {
        if (doNotUseAdditive.Checked == true)
        {
            foreach (string engine in _checkedEngines) // Grab selected engines
            {
                query = lines[i];

                _smartThreadPool2.QueueWorkItem(
                new Amib.Threading.Func<string, string, int, int, int>(scrape),
                query, engine, iia, useProxies);

                iia++;
            }
        }
    }
}
else
{
    // Wait
    wait.WaitOne();
}

問題は、for ループ内でその if ステートメントを実行できないことです。これは、戻ってきたときにループ内の場所を覚えていないためです。

私は使用しています:

ManualResetEvent wait = new ManualResetEvent(false);  //global variable

「一時停止・再開」へ

Xスレッドが使用された後、何らかの方法でループを一時停止し、スレッドが使用可能になったら戻ってループを続行する必要があります。

何か案は?

4

1 に答える 1

3

リスト内のすべてのアイテムを別のスレッドで処理するのは良い考えではないと思います。カスタムスレッドプールを使用しても、実際にはエラーが発生しやすくなります (そして、あなたの例は私の意見を証明しています)。

まず、作業スレッドの数を正しく決定する必要があります。計算集約型の操作 (いわゆる CPU バウンド操作) を扱っているようで、論理プロセッサの数と等しい数の作業スレッドを使用する必要があります。

Parallel LINQを使用して、すべての作業セットを適切な量のチャンクに分割し、それらのチャンクを並行して処理できます。

Joe Albahari は、このトピックに関する優れた一連の投稿を行っています: Threading in C#. パート 5. 並列プログラミング。

PLINQ を使用した擬似コードを次に示します。

lines
  .AsParallel()
  .WithDegreeOfParallelism(YourNumberOfProcessors)
  .Select(e => ProcessYourData(e));
于 2012-11-29T12:36:05.643 に答える