Gho*_*ter 2 .net c# asynchronous
这是代码:
static async Task Main(string[] args)
{
var t = new Task(async () => await AsyncTest());
t.Start();
t.Wait();
Console.WriteLine("Main finished");
}
private static async Task AsyncTest()
{
Thread.Sleep(2000);
await Task.Delay(2000);
Console.WriteLine("Method finished");
}
Run Code Online (Sandbox Code Playgroud)
我的期望是t.Wait()实际上将等待AsyncTest方法完成,并且输出将是:
Method finished
Main finished
Run Code Online (Sandbox Code Playgroud)
实际上输出只有Main finished。当您await Task.Delay(2000)在AsyncTest内部点击时,Wait()即完成。如果t.Wait()用await t/ await Task.WhenAll(t)/ 替换,也会发生同样的情况Task.WaitAll(t)。
解决方案是将方法重写为同步实现,或者直接在AsyncTest()上调用Wait()。但是,问题是为什么它以这种奇怪的方式起作用?
PS这是代码的简化版本。我试图实现延迟的任务执行。实际上,Task对象是由程序的一个部分创建的,然后在某些特定条件之后由另一部分执行。
UPD:重写VAR t = new Task(async () => await AsyncTest())来var t = new Task(()=> AsyncTest().Wait())还解决了问题。虽然我仍然不太明白为什么Task无法在委托中使用async / await正常工作。
我仍然不太明白为什么Task在委托内部无法通过async / await正常工作。
因为Task构造函数仅用于创建委托任务 -即代表要运行的同步代码的任务。由于代码是同步的,因此您的asynclambda被视为async voidlambda,这意味着Task实例将不会异步等待AsyncTest完成。
更重要的是,在Task构造函数应该永远不会被任何代码中使用,任何地点,以任何理由。它实际上有零个有效用例。
一个很好的替代品Task.Task是Task.Run,它确实了解asynclambda。
在我的真实程序中,任务已推迟执行。任务对象在一个位置创建,然后在特定条件由程序的另一部分执行之后再创建。
在这种情况下,请使用异步委托。具体来说,Func<Task>。
static async Task Main(string[] args)
{
Func<Task> func = AsyncTest;
// Later, when we're ready to run.
await func();
Console.WriteLine("Main finished");
}
private static async Task AsyncTest()
{
Thread.Sleep(2000);
await Task.Delay(2000);
Console.WriteLine("Method finished");
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
146 次 |
| 最近记录: |