我有一个IEnumerable,其中包含许多需要并行处理的项目。这些项目不是CPU密集型的。 理想情况下,这些项目应该在100个或更多线程上同时执行。
我已尝试使用Parallel.ForEach()执行此操作。这可行,但问题是新线程产生得太慢。在Parallel.Foreach()到达100个线程之前需要(太长)的时间。我知道有一个MaxDegreeOfParallelism属性,但这是一个最大值,而不是最小值。
有没有办法在100个线程上立即执行foreach? ThreadPool.SetMinThreads是我们希望避免的,因为它会对整个过程产生影响。
自定义分区程序是否可以解决方案?
答案 0 :(得分:0)
我以超时5秒的速度ping了很多设备。如果只有4个线程(4个线程),你会如何尽快完成?
我将假设您在局域网上使用ping设备,并且每个设备都可通过IP地址识别和访问。
namespace PingManyDevices {
public class DeviceChecker {
public async Task<PingReply[]> CheckAllDevices(IEnumerable<IPAddress> devices) {
var pings = devices.Select(address => new Ping().SendPingAsync(address, 5000));
return await Task.WhenAll(pings);
}
/***
* Maybe push it a little further
***/
public async Task<PingReply[]> CheckAllDevices(IEnumerable<IPAddress> devices) {
var pings = devices.AsParallel().Select(address => new Ping().SendPingAsync(address, 5000));
return await Task.WhenAll(pings);
}
}
}
答案 1 :(得分:-2)
我使用ThreadPool而不是Parallel成功了:
public static void ThreadForEach<T>(this IEnumerable<T> items, Action<T> action)
{
var mres = new List<ManualResetEvent>();
foreach (var item in items)
{
var mre = new ManualResetEvent(false);
ThreadPool.QueueUserWorkItem((i) =>
{
action((T)i);
mre.Set();
}, item);
mres.Add(mre);
}
mres.ForEach(mre => mre.WaitOne());
}
在我必须使用它的情况下,它比使用Parallel.ForEach的尝试运行得更快。我只能推测它是因为它试图使用已经存在的线程(而不是花费开销来创建新的线程)。