C# 任务。等待不';不要等待异步方法完成
代码如下:C# 任务。等待不';不要等待异步方法完成,c#,.net,asynchronous,C#,.net,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 Ta
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
实际上,输出只有主完成
。Wait()就在您点击Wait Task.Delay(2000)
inside AsyncTest时完成。如果将t.Wait()
解决方案是将方法重写为同步实现或直接在AsyncTest()上调用Wait()。然而,问题是为什么它以如此奇怪的方式工作
另外,这是代码的简化版本。我试图实现延迟任务执行。实际上,任务对象是由程序的一部分创建的,然后在特定条件下由另一部分执行
UPD:将vart=newtask(async()=>await AsyncTest())
重写为var t=newtask(()=>AsyncTest().Wait())
也解决了这个问题。虽然我仍然不太明白为什么任务不能正确地使用async/await内部委托。不要使用var Task=new Task(…);task.Start()代码>,只使用任务。改为运行
在第一种情况下,使用构造函数Task(Action-Action)
,所以实际上您并不等待异步方法。如果您检查real
C#而不使用asyn wait syntax sugar,您将看到asynchvoidmethodbuilder
。在Task.Run
的情况下,您使用Task.Run(Func-Func)
以接收“真实”任务
所以,如果你想使用构造函数,你应该使用注释中的方法:newtask
A from@JonSkeet:
异步方法只返回void,这意味着没有简单的方法
等待它完成的任何事情。(你几乎应该总是
避免使用异步void方法。它们实际上只适用于
为了订阅活动。)
请看这行代码:
var t = new Task(async () => await AsyncTest());
查看任务
构造函数的签名:
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);
检查这个
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");
}
还有这个
我仍然不太明白为什么任务不能在委托内部使用async/await正确工作
因为任务
构造函数仅用于创建-即表示要运行的同步代码的任务。由于代码是同步的,因此您的async
lambda将被视为async void
lambda,这意味着任务
实例不会异步等待AsyncTest
完成
更重要的是。它几乎没有有效的用例
Task.Task
的一个很好的替代品是Task.Run
,它可以理解async
lambdas
在我的实际程序中,任务延迟了执行。任务对象在一个地方创建,然后在程序的另一部分执行特定条件之后创建
在这种情况下,请使用。具体来说,Func
static async Task Main(字符串[]args)
{
Func Func=异步测试;
//等我们准备好跑步的时候。
等待函数();
控制台写入线(“主完成”);
}
专用静态异步任务AsyncTest()
{
《睡眠》(2000年);
等待任务。延迟(2000);
Console.WriteLine(“方法完成”);
}
不要使用var task=新任务(…);task.Start()代码>,只使用任务。改为运行。在我的实际程序中,任务已延迟执行。任务对象在一个地方创建,然后在程序的另一部分执行特定条件之后创建。可能重复@WiktorZychla的AsyncTest
返回任务,但async()=>wait AsyncTest()
lambda将其丢弃,因为它本身是一个操作(void
)<代码>()=>AsyncTest().Wait()
将“修复”它(由于Wait()
),仍然会出错。);var t2=t1.Unwrap();t1.Start();t2.等待()代码>这是如何回答这个问题的?虽然这个答案很有道理,但你似乎是从中复制了解释。@WiktorZychla是的,第一段来自legend JonSkeet,我最近编辑了答案,但离开了笔记本电脑,忘记了发送更改。问题是:为什么模式var t=new Task(…);t、 等待()代码>未按预期工作。
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");
}
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");
}