gpt4 book ai didi

c# - 将 Task.WhenAll 与不断增长的任务列表一起使用

转载 作者:太空宇宙 更新时间:2023-11-03 22:44:54 25 4
gpt4 key购买 nike

Task.WhenAll(IEnumerable<Task>)等待 IEnumerable 中的所有任务完成 --- 但只有列表中的任务在首次调用时完成。如果有任何事件任务添加到列表中,则不会考虑它们。这个简短的例子演示了:

    List<Task> _tasks = new List<Task>();

public async Task QuickExample()
{
for(int n =0; n < 6; ++n)
_tasks.Add(Func1(n));

await Task.WhenAll(_tasks);
Console.WriteLine("Some Tasks complete");

await Task.WhenAll(_tasks);
Console.WriteLine("All Tasks complete");
}


async Task Func1(int n)
{
Console.WriteLine($"Func1-{n} started");
await Task.Delay(2000);
if ((n % 3) == 1)
_tasks.Add(Func2(n));
Console.WriteLine($"Func1-{n} complete");
}

async Task Func2(int n)
{
Console.WriteLine($"Func2-{n} started");
await Task.Delay(2000);
Console.WriteLine($"Func2-{n} complete");
}

这个输出:

Func1-0 started
Func1-1 started
Func1-2 started
Func1-3 started
Func1-4 started
Func1-5 started
Func1-5 complete
Func1-3 complete
Func2-1 started
Func1-1 complete
Func1-0 complete
Func1-2 complete
Func2-4 started
Func1-4 complete
Some Tasks complete
Func2-4 complete
Func2-1 complete
All Tasks complete
Done

第二个Task.WhenAll()在这种情况下解决了问题,但这是一个相当脆弱的解决方案。在一般情况下,处理此问题的最佳方法是什么?

最佳答案

您正在修改 List<>不锁定它......你喜欢过危险的生活:-) 保存 Count_tasks在做 WaitAll 之前, 然后在 WaitAll 之后检查Count_tasks .如果不同,再做一轮(所以你需要一个 while 围绕着 WaitAll

int count = _tasks.Count;

while (true)
{
await Task.WhenAll(_tasks);

lock (_tasks)
{
if (count == _tasks.Count)
{
Console.WriteLine("All Tasks complete");
break;
}

count = _tasks.Count;
Console.WriteLine("Some Tasks complete");
}
}

async Task Func1(int n)
{
Console.WriteLine($"Func1-{n} started");
await Task.Delay(2000);

if ((n % 3) == 1)
{
lock (_tasks)
{
_tasks.Add(Func2(n));
}
}

Console.WriteLine($"Func1-{n} complete");
}

我将添加第二个(可能更正确的解决方案),它与您正在做的不同:您可以简单地 awaitTask来自 Task生成它们的 s,没有将它们级联到 _tasks收藏。如果 A 创建了 B,那么 A 在 B 完成之前不会完成。显然你不需要添加新的 Task s 到 _tasks收藏。

关于c# - 将 Task.WhenAll 与不断增长的任务列表一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50438309/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com