这是代码:
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");
}
我的期望是t.Wait()
实际上会等待AsyncTest
方法完成和输出将是:
Method finished
Main finished
实际上输出只有Main finished
。 Wait() 在您点击的那一刻完成await Task.Delay(2000)
在 AsyncTest 中。如果你替换也会发生同样的情况t.Wait()
with await t
/ await Task.WhenAll(t)
/ Task.WaitAll(t)
.
解决方案是将方法重写为同步实现或直接在AsyncTest()上调用Wait()。然而,问题是为什么它会以如此奇怪的方式工作?
附:这是代码的简化版本。我试图实现延迟任务执行。实际上,任务对象是由程序的一个部分创建的,然后在某些特定条件后由另一部分执行。
UPD:重写 vart = new Task(async () => await AsyncTest())
to var t = new Task(()=> AsyncTest().Wait())
也解决了这个问题。虽然我仍然不太明白为什么 Task 不能与委托内部的 async/await 一起正常工作。
我仍然不太明白为什么任务不能与委托内部的 async/await 一起正常工作。
因为Task
构造函数仅用于创建委派任务- 即代表要运行的同步代码的任务。由于代码是同步的,您的async
lambda 被视为async void
拉姆达,这意味着Task
实例不会异步等待AsyncTest
去完成。
更重要的是,the Task构造函数永远不应该以任何理由在任何代码中、任何地方使用。它的有效用例实际上为零。
一个很好的替代品Task.Task
is Task.Run
, which does理解async
拉姆达。
在我的真实程序中,任务已延迟执行。任务对象在一个地方创建,然后在特定条件后由程序的另一部分执行。
在这种情况下,请使用异步委托。具体来说,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");
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)