Какой лучший способ параллельной обработки в С # с некоторыми асинхронными методами. Позвольте мне объяснить с помощью простого кода
Пример сценария: у нас есть человек и 1000 текстовых файлов от него. мы хотим проверить, что его текстовые файлы не содержат конфиденциальных ключевых слов, и если один из его текстовых файлов содержит конфиденциальные ключевые слова, мы помечаем его как ненадежный. Метод, который проверяет это, является асинхронным, и, как только мы обнаружили одно из важных ключевых слов, дальнейшая обработка не требуется, и цикл проверки должен быть прерван для этого человека.
Чтобы добиться максимальной производительности и сделать это так быстро, мы должны использовать простой псудокод для параллельной обработки:
boolean sesitivedetected=false;
Parallel.ForEach(textfilecollection,async (textfile,parallelloopstate)=>
{
if (await hassensitiveasync(textfile))
{
sensitivedetected=true;
parallelloopstate.break()
}
}
if (sensitivedetected)
markuntrusted(person)
Проблема в том, что Parallel.ForEach
не ждут завершения асинхронных задач, поэтому оператор if (sensitivedetected)
запускается сразу после завершения создания задачи. Я читал другие вопросы, такие как писать parallel.for с помощью async и async / await и Parallel.For и много других страниц. Эти темы полезны, когда вам нужно, чтобы результаты асинхронных методов были собраны и использованы позже, но в моем сценарии выполнение цикла должно быть завершено как можно скорее.
Обновление: образец кода:
Boolean detected=false;
Parallel.ForEach(UrlList, async (url, pls) =>
{
using (HttpClient hc = new HttpClient())
{
var result = await hc.GetAsync(url);
if ((await result.Content.ReadAsStringAsync()).Contains("sensitive"))
{
detected = true;
pls.Break();
}
}
});
if (detected)
Console.WriteLine("WARNING");
Parallel.For()
сasync
методами. Ваш вопрос действительно слишком широк, как указано; вы не включили хороший минимальный воспроизводимый пример, и существует множество способов интерпретации вашего псевдокода с точки зрения того, что каждая его часть делает в реальном коде. Но вы можете просто запускать задачи вместо использованияParallel
, используяCancellationTokenSource
по мере необходимости для связи с этими задачами, если их нужно прервать, и, конечно, с циклом, который их создает. Пожалуйста, улучшите вопрос, если вам нужен более конкретный совет. - person Peter Duniho   schedule 09.05.2017Parallel.For()
, и вы действительно должны использовать методasync
, который определяет, следует ли продолжать цикл, и этот метод является единственным ожидаемым выражением в вашем делегатеParallel.For()
, тогда вы можете просто использовать его синхронно, то естьif (hassensitiveasync(textfile).Result)
. Как говорится в деталях реализации, это плохая практика, но если вы загоните себя в угол, иногда вам придется оставить следы. - person Peter Duniho   schedule 09.05.2017Parallel.For
с async, прочтите это: ссылка. Я думаю, что этот `AsyncEnumerator ', вероятно, решит мою проблему, но я не знаю, как это сделать. Действительно, если вам нужен более точный код, я предоставлю его в обновленном Вопросе. @PeterDuniho - person X X   schedule 09.05.2017Task
s. - person Aron   schedule 09.05.2017Task.WhenAll
. Вы можете запустить 100GetAsync
вызовов, поместить их в массив и ожидать их всех. - person Panagiotis Kanavos   schedule 09.05.2017Parallel.For/ForEach
разделит данные и использует одну задачу для обработки каждого раздела. Когда вы это делаете, вы не хотите и не нуждаетесь в асинхронных операциях. - person Panagiotis Kanavos   schedule 09.05.2017Task.WhenAll
, но почему я должен ждать завершения всех задач. Результат выполнения задачи с желаемым результатом может отменить все другие незавершенные задачи. Как это сделать? - person X X   schedule 09.05.2017SemaphoreSlim
. - person Aron   schedule 10.05.2017