首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >生成工作线程

生成工作线程
EN

Stack Overflow用户
提问于 2010-04-23 01:53:10
回答 4查看 1K关注 0票数 4

在C#中,

如何派生多个线程,然后在返回整个结果集之前按顺序将结果添加到列表中?

有哪些最佳实践?

到目前为止,我使用ManualResetEvent来通知线程何时处理了最后一个元素。

但当它返回时,我需要让它们按顺序合并结果集,这样我们就不会与返回值列表(总结果)发生争用问题。

EN

回答 4

Stack Overflow用户

发布于 2010-04-23 01:59:20

如果您在生成线程之前知道最终的顺序(您的“顺序”意味着),您可以向每个线程传递一个索引,并让它将其结果写入数组中的“槽”中。因此,当所有线程都完成处理(以任何顺序)时,结果将已经被正确排序,完全避免了对后处理排序的需要。

票数 1
EN

Stack Overflow用户

发布于 2010-04-23 02:11:07

任务并行库现在是Reactive Extensions for .NET Framework的一部分,它使得这样的事情变得微不足道。有一组用于并行化代码的Parallel结构,以及一组线程安全的Concurrent{Container}s,您可以将它们与它们一起使用。

下面是使用Parallel.ForConcurrentBag存储结果的一组数字平方的示例。

代码语言:javascript
复制
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即可。

票数 1
EN

Stack Overflow用户

发布于 2010-04-23 02:16:49

例如,如果您使用的是Task4,则可以使用.Net类。以下是合并列表的示例

代码语言:javascript
复制
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);
}

和你的函数

代码语言:javascript
复制
List<string> SomeFunction()
{
    return new List<string>{"1","2"};
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2693187

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档