Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何将任务添加到task.WhenAll正在等待的集合中?_C#_Asynchronous_Async Await - Fatal编程技术网

C# 如何将任务添加到task.WhenAll正在等待的集合中?

C# 如何将任务添加到task.WhenAll正在等待的集合中?,c#,asynchronous,async-await,C#,Asynchronous,Async Await,当所有的都在等待时,是否可以将任务添加到任务列表中 我想等待所有任务完成,并且有可能在初始化后创建新任务。但是这里的Task.whalll并不等待稍后添加到集合中的新任务 List<Task> tasks = new List<Task>(); var task1 = Task.Run(async () => { Debug.WriteLine("task #1 started"); await Task.Delay(Tim

当所有的都在等待时,是否可以将任务添加到任务列表中

我想等待所有任务完成,并且有可能在初始化后创建新任务。但是这里的
Task.whalll
并不等待稍后添加到集合中的新任务

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

var task1 = Task.Run(async () =>
    {
        Debug.WriteLine("task #1 started");
        await Task.Delay(TimeSpan.FromSeconds(20));
        Debug.WriteLine("task #1 finished");
    });

var task2 = Task.Run(async () =>
{
    Debug.WriteLine("task #2 started");
    await Task.Delay(TimeSpan.FromSeconds(30));
    Debug.WriteLine("task #2 finished");
});

var task3 = Task.Run(async () =>
{
    Debug.WriteLine("task #3 started");
    await Task.Delay(TimeSpan.FromSeconds(10));
    var inner = Task.Run(async () =>
    {
        Debug.WriteLine("inner task started");
        await Task.Delay(TimeSpan.FromSeconds(40));
        Debug.WriteLine("inner task finished");
    });

    tasks.Add(inner);

    Debug.WriteLine("task #3 finished");
});

tasks.Add(task1);
tasks.Add(task2);
tasks.Add(task3);

await Task.WhenAll(tasks);
Debug.WriteLine("All finished");
List tasks=newlist();
var task1=Task.Run(异步()=>
{
Debug.WriteLine(“任务1已启动”);
等待任务延迟(时间跨度从秒(20));
Debug.WriteLine(“任务1完成”);
});
var task2=Task.Run(异步()=>
{
Debug.WriteLine(“任务2已启动”);
等待任务延迟(时间跨度从秒(30));
Debug.WriteLine(“任务2完成”);
});
var task3=Task.Run(异步()=>
{
Debug.WriteLine(“任务3已启动”);
等待任务延迟(时间跨度从秒(10));
var internal=Task.Run(异步()=>
{
WriteLine(“内部任务已启动”);
等待任务延迟(时间跨度从秒(40));
Debug.WriteLine(“内部任务完成”);
});
任务。添加(内部);
Debug.WriteLine(“任务3完成”);
});
任务。添加(任务1);
任务。添加(任务2);
任务。添加(任务3);
等待任务。何时(任务);
Debug.WriteLine(“全部完成”);
输出:

task #2 started
task #3 started
task #1 started
task #3 finished
inner task started
task #1 finished
task #2 finished
All finished
inner task finished < didn't wait for this to finish
任务#2已启动
任务3已开始
任务1已启动
任务#3已完成
内部任务已启动
任务#1已完成
任务#2已完成
全部完成
内部任务已完成<未等待此任务完成

这是因为
任务。添加(内部)
等待任务。所有(任务)
之后执行。要回答您的问题,首先您需要澄清task#3和task inner之间的关系。在我看来,内部任务应该是任务3的一部分。也就是说,在内部任务完成之前,任务3无法完成

await inner;   //instead of tasks.Add(inner);   

Task.whalll
始终在任务实际开始等待之前删除对任务的引用。这确实意味着可以在等待过程中更新原始集合,但所有的都完全忽略这些更改

相反,我建议在循环中运行
。大致如下:

while(tasks.Count > 0) {
    await Task.WhenAll(tasks);
    tasks = tasks.Where(t => !t.IsCompleted);
}

(详细说明您是否希望将
任务
本身保持不变,该变量的正确数据类型是什么,等等,留给读者作为练习填写)

如果查看,您将看到在内部机制启动之前复制了集合/数组。因此,对原始集合的任何更改都不会被观察到。我认为最好的方法是手动循环-
while(tasks.Count>0){wait Task.WhenAll(tasks);tasks=tasks.Where(t=>!t.IsCompleted);}
作为sketch@Damien_The_Unbeliever谢谢。我认为这是最好的解决办法。你不想写下来作为答案吗?@Blendester:我发现当人们问这个问题时,他们通常想要的是一个管道,比如TPL数据流。谢谢。但那是为了示威。新任务可以从任何位置添加到任务中。我的问题是,我希望当方法结束时,所有任务都能完成。也许我解决了一个错误的问题,但我同意这是对原始问题的解决方案,这肯定是一种代码气味。如果任务A依赖于另一个任务B的完成,那么任务A的执行应该等待任务B的
完成。有关关系的更多信息,请参见下面Cheng Chen的回答。