1

URLのリストでプログラムを実行し、それらを処理するために限られた数のスレッドを開こうとしています。問題は、siteUrls.Count が 18 であっても、listPosition が 18 のときに while ループが実行されることです。しかし、追加したテスト メッセージボックスは表示されません。スレッド コード自体には、スレッドの作業の最後に currentThreads を実行するロッカーがあります。

条件が (18<18) になったときに while ループを開始するのはなぜですか? 18 でスレッドを起動しようとするのに、メッセージ ボックスが表示されないのはなぜですか? リスト項目の数よりも多くのスレッドを配置した場合にのみ問題が発生します。listPositionが_siteUrls.Countに等しい場合、ループを実行すべきではないと思うので、私には奇妙です。スレッドの開始とそうでないことをさまざまな「待機」を追加しようとしましたが、それでも機能しません。

ps listPositionを増やす前に5msの待機を追加すると、より安定します。より適切にプログラムできるようにするには、正確に何を待つ必要がありますか?

pps Thread は、lock (ThreadsMinus) { currentThreads--;} を実行する以外は、どのカウンターも操作しません。

  listPosition = 0;

    while (listPosition < siteUrls.Count)
    {
        if (listPosition == 18)
        {
            MessageBox.Show("18");
        }
        currentThreads++;
        var t = new Thread(() => Register(siteUrls[listPosition], listPosition));
        t.Start();

        if (listPosition == 18)
        {
            MessageBox.Show("18");
        }
        while (currentThreads >= maxThreads)
        {
            Thread.Sleep(50);
        }
         listPosition++;
    }
4

2 に答える 2

2

コードは、安全でない方法でカウンター(listPositionおよび)を操作します。各カウンターへのアクセスをごcurrentThreads利用ください。Interlocked.IncrementInterlocked.Decrementlock

また、サンプルからはcurrentThreads(Mike Parkhillが指摘したように)減少している場所が不明です。これが無限ループの原因である可能性が最も高いです。

于 2012-12-11T03:11:07.517 に答える
1

次のことを試してください(ここでもcurrentTheadsをロックする必要があることに注意してください)。

while (listPosition < siteUrls.Count)
{


    lock(ThreadsMinus){
      // only start a new thread if we haven't hit the maximum yet, otherwise keep spinning
      if (currentThreads < maxThreads){
         currentThreads++;
         var t = new Thread(() => Register(siteUrls[listPosition], listPosition));
          t.Start();
          listPosition++;
      } 
    }

}

maxThreadsの下にいる場合にのみ新しいスレッドが起動しますが、すべての反復でスレッドが開始されるわけではないため、スレッドが使用可能になるまで、任意のlistPositionに対して複数回反復できます。したがって、リストに18個のURLしかない場合でも、Registerメソッドにかかる時間に応じて、すべてが処理される前に1000回ループしながらそれを繰り返すことができます。

于 2012-12-11T03:09:59.357 に答える