Параллельная обработка / параллельное программирование в C # - PullRequest
4 голосов
/ 02 сентября 2011

Мне нужно обработать более одной функции, которая работает и выполняет результаты, возвращающие записи одного и того же типа.Я использую C # в Visual Studio 2010, учитывая, что у меня есть следующие функции:

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 заполнялись одновременно, если это возможно.

Ответы [ 4 ]

7 голосов
/ 02 сентября 2011

Взгляните на параллельную библиотеку задач (TPL) , которая была представлена ​​в .NET Framework 4 (то есть в Visual Studio 2010).Если говорить более конкретно, с точки зрения 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); }
);

PS: как только ваши методы выполняются параллельно, вам нужно убедиться, что ни один из них не имеет побочных эффектов, которые могли быв результате другие методы не работают должным образом.(Например, если эти методы читают и изменяют одни и те же статические поля, принадлежащие вашему классу Search, это может привести к проблемам.)

2 голосов
/ 02 сентября 2011

Используя 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 не гарантирует, что операции будут асинхронными. Если вам нужен garuntee, используйте Задачи, как указано выше.

2 голосов
/ 02 сентября 2011
//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 голос
/ 02 сентября 2011

Это эскиз возможного решения: создайте задачи для каждого метода, который вы хотите запустить, запустите каждую задачу, а затем 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);
...