以下是代码:
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。等一下()就在你点击await Task.Delay(2000)在AsyncTest里面的时候就已经完成了。如果将t.Wait()替换为await t / await Task.WhenAll(t) / Task.WaitAll(t),也会发生同样的情况。
解决方案是重写方法以同步实现或直接在AsyncTest()上调用Wait()。然而,问题是,为什么它的工作方式如此奇怪?
它是代码的简化版本。我试图实现延迟的任务执行。实际上,Task对象是由程序的一部分创建的,然后在特定的条件下由另一部分执行。
UPD:将var t = new Task(async () => await AsyncTest())重写为var t = new Task(()=> AsyncTest().Wait())也解决了这个问题。尽管我仍然不太明白为什么任务不能在异步/等待内部委托中正确工作。
发布于 2019-06-04 13:50:13
我仍然不太明白为什么任务不能在异步/等待内部委托中正确工作。
因为Task构造函数仅用于创建委托任务 --即表示要运行的同步代码的任务。由于代码是同步的,所以您的async lambda被视为async void lambda,这意味着Task实例不会异步地等待AsyncTest完成。
更重要的是,构造函数永远不应该在任何代码中,任何地方,出于任何原因被使用。。它几乎没有有效的用例。
Task.Task的一个很好的替代品是Task.Run,它确实理解async lambdas。
在我真正的程序中,任务已经推迟了执行。任务对象在一个地方创建,然后在程序的另一部分执行特定条件之后创建。
在这种情况下,使用异步委托。具体来说,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");
}发布于 2019-06-04 10:29:39
@JonSkeet的报价:
异步方法只返回void,这意味着没有简单的方法等待它完成。(您几乎总是应该避免使用异步空方法。它们实际上只有为了订阅事件才能使用。)
因此,看看这行代码:
var t = new Task(async () => await AsyncTest());查看Task构造函数的签名:
public Task(Action action);
public Task(Action action, CancellationToken cancellationToken);
public Task(Action action, TaskCreationOptions creationOptions);
public Task(Action<object> action, object state);
public Task(Action action, CancellationToken cancellationToken, TaskCreationOptions creationOptions);
public Task(Action<object> action, object state, CancellationToken cancellationToken);
public Task(Action<object> action, object state, TaskCreationOptions creationOptions);
public Task(Action<object> action, object state, CancellationToken cancellationToken, TaskCreationOptions creationOptions);它们都是Actions,如您所知,Action具有void返回类型。
static async Task Main(string[] args)
{
// best way to do it
await AsyncTest();
Console.WriteLine("Main finished");
}
private static async Task AsyncTest()
{
// Don't use thread sleep, await task delay is fine
// Thread.Sleep(2000);
await Task.Delay(2000);
Console.WriteLine("Method finished");
}发布于 2019-06-04 10:30:03
看看这个
public static async Task Main(string[] args)
{
var t = Task.Factory.StartNew(async () => await AsyncTest());
//t.Start();
t.Result.Wait();
t.Wait();
Console.WriteLine("Main finished");
}
private static async Task AsyncTest()
{
//Thread.Sleep(2000);
await Task.Delay(2000);
Console.WriteLine("Method finished");
}而这个链接
https://stackoverflow.com/questions/56441486
复制相似问题