C# 如何让多个线程处理相同的IEnumerable结果?
我有一个方法,它返回一个C# 如何让多个线程处理相同的IEnumerable结果?,c#,ienumerable,task,C#,Ienumerable,Task,我有一个方法,它返回一个IEnumerable,当然是用yield-return处理的。我希望有多个线程来处理这个结果,当然不需要重复它,也不需要线程安全。我将如何实现这一点 var result = GetFiles(source); for (int i = 0; i < Environment.ProcessorCount; i++) { tasks.Add(Task.Factory.StartNew(() => { ProcessCopy(result); }));
IEnumerable
,当然是用yield-return处理的代码>。我希望有多个线程来处理这个结果,当然不需要重复它,也不需要线程安全。我将如何实现这一点
var result = GetFiles(source);
for (int i = 0; i < Environment.ProcessorCount; i++)
{
tasks.Add(Task.Factory.StartNew(() => { ProcessCopy(result); }));
}
Task.WaitAll(tasks.ToArray());
您必须为每个ProcessCopy()
调用选择一系列项-现在您正在向每个线程传递文件的完整枚举-请记住,您要传递的IEnumerable
有一个名为GetEnumerator()
-的方法,只有在调用该方法时(foreach在后台为您执行此操作)返回真正的枚举数,然后可以使用它逐个枚举项。由于传递的是IEnumerable
,因此每个线程都在调用GetEnumerator()
,从而枚举所有文件
相反,要使每个文件都具有ProcessCopy()
处理一个文件,请执行以下操作:
foreach(string file in GetFiles(source))
{
string fileToProcess = file;
tasks.Add(Task.Factory.StartNew(() => { ProcessCopy(fileToProcess); }));
}
Task.WaitAll(tasks.ToArray());
我不担心处理器数量-让TPL和线程池计算出要运行多少线程才能获得最佳性能。使用Parallel.ForEach方法可以轻松做到这一点
每个迭代都将在任务管理器中排队。当执行所有迭代时,循环将退出
var result = GetFiles(source);
Parallel.ForEach(result, current => {
ProcessCopy(current);
});
Console.WriteLine("Done");
为什么不使用一个简单的LINQ查询来做您想要做的事情呢
var tasks =
from f in GetFiles(source)
select Task.Factory.StartNew(() => { ProcessCopy(f); });
Task.WaitAll(tasks.ToArray());
幕后TPL为您处理所有棘手的环境。ProcessorCount
内容。基本上与BrokenGlass相同,但使用我喜欢的LINQ。Parallel.ForEach似乎是迄今为止最干净的,但这绝对是我应该思考这个问题的方式。
var tasks =
from f in GetFiles(source)
select Task.Factory.StartNew(() => { ProcessCopy(f); });
Task.WaitAll(tasks.ToArray());