我是否总是必须等待一次性对象的异步方法而不是返回其任务?
Do I always have to await on an Async method of a disposable object instead of returning its Task?
我似乎陷入了一个巨大的困境,经过数小时的调试后,我发现该进程超出了 RunGame1() 中的“使用”范围,并且任务在等待时从未完成。
async void Execute(object o) // ICommand.Execute
{
// fire and forget
try
{
await RunGame2(); // RunGame1() fails to complete
}
finally
{ ... }
}
// This fails due to process going out of "using" scope and never completes
Task RunGame1()
{
var info = new ProcessStartInfo("game.exe") { CreateNoWindow = true };
using var process = new Process() { StartInfo = info };
process.Start();
return process.WaitForExitAsync();
}
// Have to await the Task inside the method
async Task RunGame2()
{
var info = new ProcessStartInfo("game.exe") { CreateNoWindow = true };
using var process = new Process() { StartInfo = info };
process.Start();
await process.WaitForExitAsync();
}
是否有解决此问题的模式,以便我可以 return 任务来保存编译器制作额外的状态机,或者它只是需要注意的事情?
这确实是一个常见的陷阱 - 我已经看到几个类似的错误。
简而言之:
- 没有,你并不总是需要
await
一项任务,有时它可以积极地有利于避免异步机制的开销——尤其是在像 file/network IO 循环这样的紧凑代码中,but(这是一个很大的但是)
- if 这意味着您正在逃离
try
/finally
区域(其中还包括 using
和 lock
,尽管 async
代码中的 lock
存在其他更大的问题),那么 你需要考虑到这一点 ,这通常意味着“是的,你需要await
"
如果有一个分析器在非async
方法中发现Task[<T>]
/ValueTask[<T>]
的return
就好了,在这样的区域中,因为它几乎总是一个错误,并且有几次不是(finally
与返回的东西无关)它可能是压制。
我似乎陷入了一个巨大的困境,经过数小时的调试后,我发现该进程超出了 RunGame1() 中的“使用”范围,并且任务在等待时从未完成。
async void Execute(object o) // ICommand.Execute
{
// fire and forget
try
{
await RunGame2(); // RunGame1() fails to complete
}
finally
{ ... }
}
// This fails due to process going out of "using" scope and never completes
Task RunGame1()
{
var info = new ProcessStartInfo("game.exe") { CreateNoWindow = true };
using var process = new Process() { StartInfo = info };
process.Start();
return process.WaitForExitAsync();
}
// Have to await the Task inside the method
async Task RunGame2()
{
var info = new ProcessStartInfo("game.exe") { CreateNoWindow = true };
using var process = new Process() { StartInfo = info };
process.Start();
await process.WaitForExitAsync();
}
是否有解决此问题的模式,以便我可以 return 任务来保存编译器制作额外的状态机,或者它只是需要注意的事情?
这确实是一个常见的陷阱 - 我已经看到几个类似的错误。
简而言之:
- 没有,你并不总是需要
await
一项任务,有时它可以积极地有利于避免异步机制的开销——尤其是在像 file/network IO 循环这样的紧凑代码中,but(这是一个很大的但是) - if 这意味着您正在逃离
try
/finally
区域(其中还包括using
和lock
,尽管async
代码中的lock
存在其他更大的问题),那么 你需要考虑到这一点 ,这通常意味着“是的,你需要await
"
如果有一个分析器在非async
方法中发现Task[<T>]
/ValueTask[<T>]
的return
就好了,在这样的区域中,因为它几乎总是一个错误,并且有几次不是(finally
与返回的东西无关)它可能是压制。