Parallel.ForEach выполнить множество операций в отдельных потоках - C#
Формулировка задачи:
Народ, кто-нибудь может объяснить в каких ситуациях нужно использовать перегрузку Parallel.ForEach, в которой есть localInit, body, localFinally. Я хочу парсить сайт и в localFinally помещать результат парсинга в блокирующую очередь, но нельзя этого сделать, так как я передаю в метод в качестве первого параметра string (IEnumerable<TSource> source), то и в остальных методах идёт инициализация и финальные действия тоже с string. Короче что-то я вообще не въеду, где это может пригодится. А то что я хочу делать походу проще оставить как есть сейчас, всё делается в body. Я себе это представлял как с BackgroundWorker, типа как события в нём body это как DoWork, localFinally это как RunWorkerCompleted.
Эта перегрузка, о которой я говорю.
public static ParallelLoopResult ForEach<TSource, TLocal>( IEnumerable<TSource> source, ParallelOptions parallelOptions, Func<TLocal> localInit, Func<TSource, ParallelLoopState, TLocal, TLocal> body, Action<TLocal> localFinally);
public void ParseAsync(string[] webSites) { int parsedDocs = 0; ConcurrentQueue<string> errors = new ConcurrentQueue<string>(); ConcurrentQueue<T> infos = new ConcurrentQueue<T>(); ParallelOptions parOpt = new ParallelOptions(); _cancellationTokenSource = new CancellationTokenSource(); parOpt.CancellationToken = _cancellationTokenSource.Token; Func<string> localInit = () => { return ""; }; Func<string, ParallelLoopState, string, string> body = (site, pLoopState, something) => { T info; if (parOpt.CancellationToken.IsCancellationRequested) parOpt.CancellationToken.ThrowIfCancellationRequested(); try { if (_webSiteParser.Parse(site, out info)) { infos.Enqueue(info); OnWebSiteParsed(info, ++parsedDocs, errors.Count); } else { OnParsingWasFailured(site, null); errors.Enqueue(site); } } catch (Exception exc) { OnParsingWasFailured(site, exc); errors.Enqueue(site); } return string.Empty; }; Action<string> localFinally = (site) => { }; Parallel.ForEach(webSites, parOpt, localInit, body, localFinally); }
Решение задачи: «Parallel.ForEach выполнить множество операций в отдельных потоках»
textual
Листинг программы
static double sum = 0.0; // Окончательный результат static object sync = new object(); // Объект для синхронизации static void Main() { // Параллельный расчет суммы корней всех чисел от 1 до 10,000,000 Parallel.ForEach(Enumerable.Range(1, 10000000), Init, Body, Finally); Console.WriteLine(sum); } // Генерирует изначальное значение для локального промежутка static double Init() { return 0.0; } // Используется в расчете локальной суммы определенной части коллекции static double Body(int x, ParallelLoopState state, double local) { return local + Math.Sqrt(x); } // Здесь происходит обращение к общему ресурсу с использованием синхронизации - расчитывается сумма локальных сумм. static void Finally(double local) { lock (sync) sum += local; }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д