任务构造函数与具有异步操作的Task.Run - 不同的行为

Fen*_*ari 4 .net c# task task-parallel-library async-await

任何人都可以解释一下,也许我错过了一些明显的东西.

这两个案例的行为似乎相同,但事实并非如此.

案例1:

案例2:

第一种情况表现如预期:等待任务在第一种情况结束后,在2秒后结束.

第二种情况很奇怪:等待任务很快就会结束,早在第一种情况发生之前.

从两个任务打印消息时很容易看到.第二个任务结束时的打印将显示差异.

我正在使用VS 2015 Preview,它可能使用Roslyn进行编译,如果这很重要的话.

Aro*_*ron 8

答案在这里http://blogs.msdn.com/b/pfxteam/archive/2011/10/24/10229468.aspx

实际上,问题是,当你试图给出一个时new Task,它只能带Action一个Func<Task>.以下是前两行,但使用正确的重载进行了重写.

Task t = Task.Run(async () => { await Task.Delay(2000); });
Run Code Online (Sandbox Code Playgroud)

Task<Task> t = new Task<Task>(async () => { await Task.Delay(2000); });
Run Code Online (Sandbox Code Playgroud)

第一个按预期创建任务.第二个创建一个任务,谁的返回类型是一个等待2000毫秒的任务.第一个例子是因为以下重载...

 public Task Run(Func<Task>);
 public Task<T> Run(Func<T>);
 public Task<T> Run(Func<Task<T>>);
 etc...
Run Code Online (Sandbox Code Playgroud)

这些重载旨在Task<Task<T>>.Unwrap()为您自动调用.

结果是在您的第二个示例中,您实际上正在等待第一个任务的开始/排队.

您可以通过修复第二个示例

var t = new Task<Task>(async () => { await Task.Delay(2000); }).Unwrap();
Run Code Online (Sandbox Code Playgroud)