1
は、ここで私が使用しているコードのサンプルです:フォースParallel.ForEachは、コレクション内の項目ごとに1つのスレッドを作る
Stopwatch s = new Stopwatch();
s.Start();
ParallelOptions po = new ParallelOptions();
// hosts contain 23 items
po.MaxDegreeOfParallelism = hosts.Count();
Parallel.ForEach(hosts, po, p =>
{
using (TcpClient tcpClient = new TcpClient())
{
IAsyncResult result = tcpClient.BeginConnect(p.Value, 80, null, null);
WaitHandle timeoutHandler = result.AsyncWaitHandle;
try
{
if (!result.AsyncWaitHandle.WaitOne(1000, false))
{
tasks.TryAdd(p.Key, new TaskCompleteResult { result = false, exc = new Exception("By timeout") });
tcpClient.Close();
}
else
{
tasks.TryAdd(p.Key, new TaskCompleteResult { result = true, exc = null });
}
tcpClient.EndConnect(result);
}
catch (Exception ex)
{
tasks.TryAdd(p.Key, new TaskCompleteResult { result = false, exc = ex });
}
finally
{
timeoutHandler.Close();
}
}
});
s.Stop();
Console.WriteLine(s.Elapsed.TotalSeconds);
だから、私たちは注意一部に取れば、それは、私の1(または多分2を与えるだろうと思ってオーバーヘッド作業)秒ですが、4秒かかります。 Parallel.ForEachは、スレッドプールの前に用意されているスレッドからスレッドを取り出したり、新しいスレッドを作成したりしますか? 1-2秒の作業はどのように達成できますか?
素敵なトリック!しかし、例外が発生したと判断するにはどうしたらいいですか?(ここではcatch(Exception ex){tasks.TryAdd(p.Key、new TaskCompleteResult {result = false、exc = ex});} ')それとも、私が気にするべきことは何もないのですか? – kseen
@kseenあなたはそれが終わったかどうかを見るためにまだWaitOneにできるはずです。使用している場合は、EndConnectを使用します –