Я пытаюсь найти оптимальный способ выполнить следующие действия потокаОптимизация параллельного выбора, ведущий к Parallel excution
- Получить список идентификаторов X из потока
- Для каждого идентификатора X перейти к БД и получить список идентификаторов Y с использованием сложного запроса (должны быть подключены параллельно)
- Объединения списков и отчетливый его
- Для каждого идентификатора Y выполнить долго выполняющуюся задачу (должны быть подключены параллельно)
Весь поток в 2-4 должен выполняться в другом потоке от 1, так что как только действие 1 вызывает действие 2, оно продолжает делать другие вещи.
В настоящее время мой поток выглядит следующим образом (это на 2-4 и окликнул 1):
private void PerformActionAsync(List<long> XIds)
{
var affectedYIds = XIds.AsParallel().SelectMany(xId =>
{
return GetAffectedYIdsLongRunning(xId);
}).Distinct();
affectedYIds.ForAll(yId=>
{
ExcuteLongRunningAction(yId);
});
}
Это не работает и как SelectMany и ForAll по-прежнему блокирует вызывающий поток, я могу заменить ForAll с новым созданием задачи, но все же SelectMany блокирует вызывающий поток. Как я могу выполнить SelectMany по-настоящему асинхронно?
В настоящее время мое лучшее решение заключается в том, чтобы обернуть реализацию всего метода Taks.Run, вопрос в том, есть ли лучший способ.
вы искали '' Parallel.For' и Parallel.Foreach' также является 'Task.ContinueWith' ? –
И Parallel.For, и Parallel.Foreach блокируют вызывающий поток, Task.ContinueWith не поддерживает объединение списков. Я обновил вопрос с более подробной информацией. – JoefGoldstein
«Блокировка вызывающего потока» - это не то же самое, что «не выполняется параллельно». '.AsParallel()' является параллельным, но не асинхронным. Является ли 'GetAffectedYIdsLongRunning' самой асинхронной? Если нет, параллель - лучшее, что вы собираетесь получить - вы можете отложить получение результатов с помощью 'Task.Run()' и объявить 'PerformActionAsync', возвращая эту' Задачу'. –