【发布时间】:2013-12-28 16:07:53
【问题描述】:
我想同时在多个对等点上执行基于网络的任务(可能会超时)。
所以我有以下代码:
Parallel.ForEach(hosts, i => SomeLongRunningNetworkTask(i));
我注意到从第六个任务开始执行延迟了约 1 秒。
所以我把代码改成:
hosts.AsParallel()
.WithDegreeOfParallelism(64)
.ForAll(i => result.Add(SomeLongRunningNetworkTask(i)));
但结果是一样的。
输出(在四核上):
Start: 44,00 ms
Start: 44,00 ms
Start: 44,00 ms
Start: 44,00 ms
Start: 44,00 ms
Start: 1025,06 ms
Start: 2024,12 ms
Start: 3024,17 ms
Start: 4024,23 ms
Start: 5024,29 ms
...
有没有一种简单的方法来使用 PLINQ 而不会出现这种奇怪的行为,或者我错过了什么?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplicationParallelTest
{
class Program
{
private DateTime Started { get; set; }
static void Main(string[] args)
{
// for testing: All Subnet IP's:
var ips = new List<IPAddress>();
for(int i=1 ; i< 255 ;i++)
ips.Add( IPAddress.Parse( "192.168.10." + i ));
var result = new Program().ExecuteAll(ips);
}
private List<Object> ExecuteAll(List<IPAddress> hosts)
{
Started = DateTime.Now;
var result = new List<Object>();
//Parallel.ForEach(hosts, i => SomeLongRunningNetworkTask(i));
hosts.AsParallel()
.WithDegreeOfParallelism(64)
.ForAll(i => result.Add(SomeLongRunningNetworkTask(i))
);
return result;
}
private Object SomeLongRunningNetworkTask(Object o)
{
Console.WriteLine("Start: " + DateTime.Now.Subtract(Started).TotalMilliseconds.ToString("F2") + " ms");
Thread.Sleep(60 * 1000);
Console.WriteLine("End: " + DateTime.Now.Subtract(Started).TotalMilliseconds.ToString("F2") + " ms");
return new Object();
}
}
}
【问题讨论】:
-
WithDegreeOfParallelism并不意味着它会使用那么多线程。它仅用于设置上限(TPL 将根据您的系统配置决定使用多少 thrad)。 -
使用 Thread.Sleep() 不会产生可用于真实代码的结果。如果要优化网络代码,请使用该网络。