在C#中,
如何派生多个线程,然后在返回整个结果集之前按顺序将结果添加到列表中?
有哪些最佳实践?
到目前为止,我使用ManualResetEvent来通知线程何时处理了最后一个元素。
但当它返回时,我需要让它们按顺序合并结果集,这样我们就不会与返回值列表(总结果)发生争用问题。
发布于 2010-04-23 01:59:20
如果您在生成线程之前知道最终的顺序(您的“顺序”意味着),您可以向每个线程传递一个索引,并让它将其结果写入数组中的“槽”中。因此,当所有线程都完成处理(以任何顺序)时,结果将已经被正确排序,完全避免了对后处理排序的需要。
发布于 2010-04-23 02:11:07
任务并行库现在是Reactive Extensions for .NET Framework的一部分,它使得这样的事情变得微不足道。有一组用于并行化代码的Parallel结构,以及一组线程安全的Concurrent{Container}s,您可以将它们与它们一起使用。
下面是使用Parallel.For和ConcurrentBag存储结果的一组数字平方的示例。
using System.Threading.Tasks;
using System.Collections.Concurrent;
namespace ParallelTest
{
class Program
{
static void Main(string[] args)
{
var results = new ConcurrentBag<int>();
Parallel.For(0, 10, i =>
{
results.Add(i * i);
});
foreach (int i in results)
System.Console.WriteLine(i);
}
}
}ConcurrentBag是一个常规的IEnumerable,正如您所看到的,我使用了一个常规的非并行foreach来打印最后的结果。
注意:所有这些东西实际上都是.NET 4.0中的标准,如果你想在.NET 3.5中使用,你只需要Rx即可。
发布于 2010-04-23 02:16:49
例如,如果您使用的是Task4,则可以使用.Net类。以下是合并列表的示例
Task<List<string>> task1 = new Task<List<string>>(SomeFunction);
Task<List<string>> task2 = new Task<List<string>>(SomeFunction);
task1.Start();
task2.Start();
var taskList = new List<Task<List<string>>> {task1, task2};
Task.WaitAll(taskList.ToArray());
List<string> res = new List<string>();
foreach (Task<List<string>> t in taskList)
{
res.AddRange(t.Result);
}和你的函数
List<string> SomeFunction()
{
return new List<string>{"1","2"};
}https://stackoverflow.com/questions/2693187
复制相似问题