你不需要实现任何队列,你可以使用Parallel.ForEach。
这正是它的设计目的。以下示例显示了Parallel.ForEach 的最简单用法。 Stopwatch 不是该功能的一部分,它仅用于测量执行时间。
Stopwatch sw = new Stopwatch();
List<Action> actions = new List<Action>();
actions.Add(() => { Thread.Sleep(1000); Console.WriteLine($"1 - {sw.ElapsedMilliseconds}"); });
actions.Add(() => { Thread.Sleep(10000); Console.WriteLine($"2 - {sw.ElapsedMilliseconds}"); });
actions.Add(() => { Thread.Sleep(3000); Console.WriteLine($"3 - {sw.ElapsedMilliseconds}"); });
actions.Add(() => { Thread.Sleep(3000); Console.WriteLine($"4 - {sw.ElapsedMilliseconds}"); });
sw.Start();
Parallel.ForEach(actions, new ParallelOptions
{
MaxDegreeOfParallelism = 2
}, action => action());
MaxDegreeOfParallelism 指定应该有多少线程运行您的操作。
如果在上面的代码中MaxDegreeOfParallelism设置为1,那么这些动作将由单个线程执行:
1 - 1002
2 - 11002
3 - 14002
4 - 17003
MaxDegreeOfParallelism 设置为 2,输出如下:
1 - 1029
3 - 3005
4 - 6009
2 - 11049
请注意,它不维护收集顺序。可以观察到,一开始有两个线程执行动作1和动作3,然后线程1执行动作2,线程2执行动作4。
MaxDegreeOfParallelism等于4,输出明显如下:
1 - 1029
3 - 3005
4 - 6009
2 - 11049
因为 4 个线程同时采取了所有的动作,并执行了这个。