Tôi đã thấy Parallel.ForEach được sử dụng không phù hợp và tôi đã tìm ra một ví dụ trong câu hỏi này sẽ giúp ích.
Khi bạn chạy mã bên dưới trong ứng dụng Console, bạn sẽ thấy cách các tác vụ được thực thi trong Parallel.ForEach không chặn chuỗi cuộc gọi. Điều này có thể ổn nếu bạn không quan tâm đến kết quả (tích cực hoặc tiêu cực) nhưng nếu bạn cần kết quả đó, bạn nên đảm bảo sử dụng Task.When ALL.
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}]");
}
}
}
Đây là kết quả:
Phần kết luận:
Sử dụng Parallel.ForEach với tác vụ sẽ không chặn chuỗi cuộc gọi. Nếu bạn quan tâm đến kết quả, hãy chắc chắn chờ đợi các nhiệm vụ.
~ Chúc mừng
Task.WaitAll
thay vìTask.WhenAll
.