【发布时间】:2018-10-12 15:28:43
【问题描述】:
我想同时开始收集Task 对象并等到所有对象都完成。以下代码显示了我想要的行为。
public class Program
{
class TaskTest
{
private Task createPauseTask(int ms)
{
// works well
return Task.Run(async () =>
// subsitution: return new Task(async () =>
{
Console.WriteLine($"Start {ms} ms pause");
await Task.Delay(ms);
Console.WriteLine($"{ms} ms are elapsed");
});
}
public async Task Start()
{
var taskList= new List<Task>(new[]
{
createPauseTask(1000),
createPauseTask(2000)
});
// taskList.ForEach(x => x.Start());
await Task.WhenAll(taskList);
Console.WriteLine("------------");
}
}
public static void Main()
{
var t = new TaskTest();
Task.Run(() => t.Start());
Console.ReadKey();
}
}
输出是:
Start 1000 ms pause
Start 2000 ms pause
1000 ms are elapsed
2000 ms are elapsed
------------
现在我想知道是否可以准备我的任务并单独启动它们。为此,我将createPauseTask(int ms)method 中的第一行从return Task.Run(async () => 更改为return new Task(async () =>
在Start() 方法中,我在WhenAll 之前添加了taskList.ForEach(x => x.Start());。但随后可怕的事情发生了。 WhenAll 调用立即完成,输出为:
Start 2000 ms pause
Start 1000 ms pause
------------
1000 ms are elapsed
2000 ms are elapsed
谁能告诉我我的错误是什么以及如何解决它?
【问题讨论】:
-
乍一看它应该可以正常工作,所以我尝试了您的确切代码,它在我的机器上工作正常。两个版本的行为基本相同。也许是环保的东西? .NET 版本等。我用的是 4.7
-
@sellotape 按照 OP 对我的描述工作:问题是虚线(代表 Task.WhenAll 的返回)被打印的位置。
-
@pere57 - 是的,很微妙。我读到“WhenAll 调用立即完成并且输出是......”意味着“1000 毫秒已过”和“2000 毫秒已过”立即打印,而它们实际上分别在 1 秒和 2 秒后打印。在我的
Task.WhenAll()确实在任务完成之前返回。 -
未开始的任务是一种糟糕的模式。无论您想完成什么,通常都可以通过不同的方式更好地完成。
标签: c# async-await task