Parallel.ForEach가 부적절하게 사용되는 것을 보았 으며이 질문의 예가 도움이 될 것이라고 생각했습니다.
콘솔 앱에서 아래 코드를 실행하면 Parallel.ForEach에서 실행 된 작업이 호출 스레드를 차단하지 않는 방법을 볼 수 있습니다. 결과 (긍정적 또는 부정적)에 신경 쓰지 않는다면 괜찮을 수 있지만 결과가 필요하다면 Task.WhenAll을 사용해야합니다.
using System;
using System.Linq;
using System.Threading.Tasks;
namespace ParrellelEachExample
{
class Program
{
static void Main(string[] args)
{
var indexes = new int[] { 1, 2, 3 };
RunExample((prefix) => Parallel.ForEach(indexes, (i) => DoSomethingAsync(i, prefix)),
"Parallel.Foreach");
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("*You'll notice the tasks haven't run yet, because the main thread was not blocked*");
Console.WriteLine("Press any key to start the next example...");
Console.ReadKey();
RunExample((prefix) => Task.WhenAll(indexes.Select(i => DoSomethingAsync(i, prefix)).ToArray()).Wait(),
"Task.WhenAll");
Console.WriteLine("All tasks are done. Press any key to close...");
Console.ReadKey();
}
static void RunExample(Action<string> action, string prefix)
{
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine($"{Environment.NewLine}Starting '{prefix}'...");
action(prefix);
Console.WriteLine($"{Environment.NewLine}Finished '{prefix}'{Environment.NewLine}");
}
static async Task DoSomethingAsync(int i, string prefix)
{
await Task.Delay(i * 1000);
Console.WriteLine($"Finished: {prefix}[{i}]");
}
}
}
결과는 다음과 같습니다.
결론:
Parallel.ForEach를 Task와 함께 사용하면 호출 스레드가 차단되지 않습니다. 결과에 관심이 있다면 작업을 기다려야합니다.
~ 건배
Task.WaitAll
대신에 사용하면 두 번째 코드 조각이 첫 번째 코드 조각과 거의 같을 것이라고 생각합니다Task.WhenAll
.