C#中的并行处理/并行编程

4

我需要处理多个函数,这些函数执行后会返回相同类型的记录。我在使用Visual Studio 2010中的C#语言。 下面是我的函数:

class Search{
public list<wrecords> GetrecordsofAAA(string term);
public list<wrecords> GetrecordsofBBB(string term);
public list<wrecords> GetrecordsofCCC(string term);
}

我正在以这种方式调用函数。
list<wrecords> records1 = Search.GetrecordsofAAA(heart);
list<wrecords> records2 = Search.GetrecordsofBBB(heart);
list<wrecords> records3 = Search.GetrecordsofCCC(heart);

这是系列处理。

如果可能的话,我需要同时填充记录1、记录2和记录3。


1
更多的是工作描述而不是问题... - Mitch Wheat
请查看Task类:http://msdn.microsoft.com/zh-cn/library/system.threading.tasks.task.aspx - Just another metaprogrammer
你学过线程/任务并行库的概念吗? - Zenwalker
4个回答

7
请查看在.NET Framework 4中引入的任务并行库(TPL),更具体地说,在TPL方面,您可以使用任务并行性来解决问题。
现在,我自己不是TPL专家,但文档建议您应该能够通过Parallel.Invoke实现您想要的功能。
using System.Threading.Tasks;
…

List<wrecords> records1 = null;
List<wrecords> records2 = null;
List<wrecords> records3 = null;
// ^ Initialize these to any default value to prevent a compile-time error.
//   The compiler cannot know that below delegates will actually be called,
//   so without the initialization you would soon get a "use of unassigned
//   variable" error.

Parallel.Invoke(
    () => { records1 = Search.GetrecordsofAAA(heart); },
    () => { records2 = Search.GetrecordsofBBB(heart); },
    () => { records3 = Search.GetrecordsofCCC(heart); }
);

附言:一旦您的方法并行执行,您需要确保它们中没有任何副作用会导致其他方法无法正常工作。(例如,如果这些方法读取并修改属于您的Search类的相同静态字段,那么可能会导致问题。)


2
//make a list of the search functions you want to call.
var Searches = new List<string, Func<string, IEnumerable<wrecord>>> {
    a => GetrecordsofAAA(a),
    a => GetrecordsofBBB(a),
    a => GetrecordsofCCC(a),
}

//Execute them in parallel and collect the results as lists of lists of wrecord
IEnumerable<IEnumerable<wrecord>> result = 
    Searches.AsParallel().Select(a => a(heart));

1
嗯...我不禁想你在这里想说更多的话? - Paul Walls
我不小心太早点击了发布 :P - albertjan
我想这要么是那只流浪宠物在干扰。 :) - Paul Walls

2
使用Task Parallel Library,您可以做类似以下的事情:
list<wrecords> records1;
lList<wrecords> records2;
lList<wrecords> records3;

Task task1 = Task.Factory.StartNew(() => records1 = Search.GetrecordsofAAA(heart));
Task task2 = Task.Factory.StartNew(() => records2 = Search.GetrecordsofBBB(heart));
Task task3 = Task.Factory.StartNew(() => records3 = Search.GetrecordsofCCC(heart));

Task.WaitAll(task1, task2, task3); // Wait for all three tasks to finish
// Do stuff after

Parallel.Invoke无法保证操作是异步的。如果您需要保证异步操作,则应像上面那样使用Tasks。


1
这是可能解决方案的草图:为要运行的每种方法创建任务,启动每个任务,然后使用WaitAll()等待每个任务完成。
     // Create an array of methods to run
     Func<object, List<WRecord>>[] methods = new[]
                                               {
                                                  s => GetRecordsOfAAA((string) s),
                                                  s => GetRecordsOfBBB((string) s),
                                                  s => GetRecordsOfCCC((string) s)
                                               };

     // Create an array of tasks
     Task<List<WRecord>>[] tasks = new Task<List<WRecord>>[methods.Length];

     // Create and start each task
     for (int i = 0; i < tasks.Length; i++)
     {
        tasks[i] = Task<List<WRecord>>.Factory.StartNew(methods[i], heart);
     }

     // Wait for all tasks to complete. Results are in tasks[n].Result
     Task.WaitAll(tasks);

实际上,我认为@stakx提出的Parallel.Invoke是一个实用方法,可以完全做到这一点,但不太冗长。 - Anders Forsgren

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接