3

この懸念に関するコードは次のとおりです。

while (true)
{
    Console.WriteLine("start " + DateTime.Now);
    ParallelOptions options = new ParallelOptions();
    options.MaxDegreeOfParallelism = -1;                
    Parallel.ForEach(hosts, item =>
    {
        using (Ping ping = new Ping())
        {
            PingReply pingReply = ping.Send(item.Value, 2000);  // timeout is 2 secs
            App.dict[item.Key].lastConnectTry = new KeyValuePair<bool, DateTime>((pingReply.Status == IPStatus.Success), DateTime.Now);
        }
    });        
    Console.WriteLine("end " + DateTime.Now);
    Thread.Sleep(15000);
}

しかし、そのアプリを実行すると、わずかに異なる結果が得られます。

start 27.04.2012 10:12:32
end 27.04.2012 10:12:42
// it took 10 seconds
start 27.04.2012 10:12:57
end 27.04.2012 10:13:02
// this took 5 secs
start 27.04.2012 10:13:17
end 27.04.2012 10:13:22
//   5 secs
start 27.04.2012 10:13:37
end 27.04.2012 10:13:42
// 5 secs
start 27.04.2012 10:13:57
end 27.04.2012 10:14:01
start 27.04.2012 10:14:16
end 27.04.2012 10:14:19
start 27.04.2012 10:14:34
end 27.04.2012 10:14:36
start 27.04.2012 10:14:51
end 27.04.2012 10:14:54
start 27.04.2012 10:15:09
end 27.04.2012 10:15:11
start 27.04.2012 10:15:26
end 27.04.2012 10:15:29
start 27.04.2012 10:15:44
end 27.04.2012 10:15:46
start 27.04.2012 10:16:01
end 27.04.2012 10:16:06
start 27.04.2012 10:16:21
end 27.04.2012 10:16:24
start 27.04.2012 10:16:39
end 27.04.2012 10:16:41
start 27.04.2012 10:16:56
end 27.04.2012 10:16:59
start 27.04.2012 10:17:14
end 27.04.2012 10:17:16

スレッドをブートストラップして作成すると、並列実行時間が正しく調整されるようになるまでに時間がかかるようです。

問題は、すべての処理を処理するのに 2 秒以上かかる理由と、処理前にスレッドをブートストラップして回避するにはどうすればよいかということです。

アップデート:

このループは、別のバックグラウンド スレッドに配置されます。

4

2 に答える 2

2

はい、スレッドプールは、負荷に基づいてスレッドの数を増やす必要があります (Parallel.ForEach とは関係ありません)。

Parallel.ForEach が新しいスレッドをスピンアップしていないことと、Parallel.Foreach がいくつかのバックグラウンドであまりにも多くのスレッドを生成していることを確認してください。

于 2012-04-27T04:28:15.577 に答える
1

実際に並列オプションを渡しているわけではありません。こちらを参照してください。

ParallelOptions options = new ParallelOptions();
options.MaxDegreeOfParallelism = -1;                
Parallel.ForEach(hosts, options, item => // note options passed through here
      // etc

これで十分に作成できない場合は、スレッドプールを増やすことができます。

System.Threading.ThreadPool.SetMinThreads System.Threading.ThreadPool.SetMaxThreads

ただし、改善が得られることがわかっていない限り、これには触れないことに注意してください。タスク コードでaPingを実行しているため、これは実行ごとに変動性を追加する可能性があります。

于 2012-04-27T04:51:56.173 に答える