gpt4 book ai didi

c# - WaitAll 用于更改列表

转载 作者:太空宇宙 更新时间:2023-11-03 13:03:49 26 4
gpt4 key购买 nike

更新以更清楚地解释事情

我有一个运行多个任务的应用程序。有些是最初创建的,有些可以稍后添加。我需要一个编程结构来等待所有任务完成。一旦所有任务完成,应该运行一些其他代码来清理事情并对其他任务生成的数据进行一些最终处理。

我已经想出了一个方法来做到这一点,但不会称之为优雅。所以我想看看是否有更好的方法。

我所做的是在 ConcurrentBag(一个线程安全集合)中保存一个任务列表。在流程开始时,我创建了一些任务并将其添加到 ConcurrentBag。如果创建了一个也需要在最后步骤之前完成的新任务,那么流程会执行它的操作,我还将它添加到 ConcurrentBag。

Task.Wait 接受一组任务作为其参数。我可以将 ConcurrentBag 转换为数组,但该数组不会包含在调用 Task.Wait 后添加到包中的任何任务。

所以我在 do while 循环中有一个两步等待过程。在循环体中,我对 Bag 生成的数组执行简单的 Task.Wait。当它完成时,意味着所有原始任务都已完成。然后在 while 测试中,我对从 ConcurrentBag 生成的新数组进行了 1 毫秒的快速测试。如果没有添加新任务,或者任何新任务也已完成,它将返回 true,因此 not 条件退出循环。

如果它返回 false(因为添加了一个未完成的新任务),我们返回并执行非定时任务。等待。然后冲洗并重复,直到完成所有新旧任务。

// defined on the class, perhaps they should be properties
CancellationTokenSource Source = new CancellationTokenSource();
CancellationToken Token = Source.Token;
ConcurrentBag<Task> ToDoList = new ConcurrentBag<Task>();


public void RunAndWait() {
// start some tasks add them to the list
for (int i = 0; i < 12; i++)
{
Task task = new Task(() => SillyExample(Token), Token);
ToDoList.Add(task);
task.Start();
}

// now wait for those task, and any other tasks added to ToDoList to complete
try
{
do
{
Task.WaitAll(ToDoList.ToArray(), Token);
} while (! Task.WaitAll(ToDoList.ToArray(), 1, Token));
}
catch (OperationCanceledException e)
{
// any special handling of cancel we might want to do
}

// code that should only run after all tasks complete
}

有没有更优雅的方法来做到这一点?

最佳答案

我建议使用 ConcurrentQueue 并在等待时删除项目。由于队列的先进先出特性,如果您到达队列中没有剩余任何任务的地步,您就知道您已经等待了所有已添加到该点的任务。

ConcurrentQueue<Task> ToDoQueue = new ConcurrentQueue<Task>();

...

while(ToDoQueue.Count > 0 && !Token.IsCancellationRequested)
{
Task task;
if(ToDoQueue.TryDequeue(out task))
{
task.Wait(Token);
}
}

关于c# - WaitAll 用于更改列表<Task>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31485375/

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