下面是示例控制臺應用程式,輸出是

每次輸出都不同并且很好,但它需要在我列印結果之前完成所有任務。似乎Parallel.ForEachAsync不是在等待所有任務完成。我在這里錯過了什么嗎?
internal class Program
{
private async static Task Main(string[] args)
{
Stopwatch sw = new Stopwatch();
sw.Start();
await TestParallel();
sw.Stop();
Console.WriteLine("Elapsed={0}", sw.Elapsed);
Console.ReadLine();
}
private static async Task TestParallel()
{
var tests = new List<int>() { 1, 2, 3, 4, 5, 6 };
var options = new ParallelOptions { MaxDegreeOfParallelism = 5,
CancellationToken = CancellationToken.None };
var responses = new List<string>();
await Parallel.ForEachAsync(tests, options, async (testno, cancellationToken) =>
{
var response = await TestTask(testno);
responses.Add(response);
});
foreach (var response in responses)
{
Console.WriteLine(response);
}
}
private static Task<string> TestTask(int testno)
{
System.Threading.Thread.Sleep(1000);
return Task.FromResult($"Test{testno}");
}
}
uj5u.com熱心網友回復:
答案如下 - 更改行 var response = new ConcurrentBag();
internal class Program
{
private async static Task Main(string[] args)
{
Stopwatch sw = new Stopwatch();
sw.Start();
await TestParallel();
sw.Stop();
Console.WriteLine("Elapsed={0}", sw.Elapsed);
Console.ReadLine();
}
private static async Task TestParallel()
{
var tests = new List<int>() { 1, 2, 3, 4 ,5,6};
var options = new ParallelOptions { MaxDegreeOfParallelism = 5, CancellationToken = CancellationToken.None };
var responses = new ConcurrentBag<string>();
await Parallel.ForEachAsync(tests, options, async (testno, cancellationToken) =>
{
var response = await TestTask(testno);
responses.Add(response);
});
foreach (var response in responses)
{
Console.WriteLine(response);
}
}
private static Task<string> TestTask(int testno)
{
System.Threading.Thread.Sleep(1000);
return Task.FromResult($"Test{testno}");
}
}
uj5u.com熱心網友回復:
回答 .NET 6 之前的版本。
我認為您的示例有點令人困惑。那是因為您使用了異步回呼。大多數異步用于 IO 目的。
要么選擇:( 這將受 CPU 限制,需要進行一些繁重的計算)
var responses = new List<string>();
var tests = new List<int>() { 1, 2, 3, 4 ,5,6};
Parallel.ForEach(tests, options, (testno) =>
{
// no async here...
var response = TestTask(testno);
// lock the shared resource.
lock(responses)
responses.Add(response);
});
foreach (var response in responses)
{
Console.WriteLine(response);
}
private static string TestTask(int testno)
{
// calculations done here
System.Threading.Thread.Sleep(1000);
return $"Test{testno}";
}
或者去:( 這是 IO 系結的,例如從外部來源獲取內容)
var tests = new List<int>() { 1, 2, 3, 4 ,5,6};
var tasks = new List<Task<string>>();
// just add the tasks to a list, so you can await them later.
// the first part (till the first await) will be completed synchronous.
// If any async/await is used, the Task.WhenAll will wait for it.
// Multiple tasks can be running simultaneously.
foreach(var t in tests)
tasks.Add(TestTask(t));
await Task.WhenAll(tasks);
foreach (var task in tasks)
{
// the current thread won't be blocked by calling the .Result here
// All tasks are already completed.
Console.WriteLine(task.Result);
}
private static async Task<string> TestTask(int testno)
{
// Getting information from external resources.
await Task.Delay(1000);
return $"Test{testno}";
}
(可能有一些錯字,沒有用VS寫)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/415008.html
標籤:
