我通常对网络服务器进行编程,起初我认为必须有连续的方法链来返回任务,所以堆栈中的内容可能会询问数据库是否完成。
最近我看到了wpf代码,它做了类似的事情:
public async void Execute(object parameter)
{
await ExecuteAsync(parameter);
}
在事件处理程序中调用。 UI似乎是响应式的,所以我猜它确实有效。它是如何工作的?这如何转化为aspnet?
答案 0 :(得分:8)
我在Best Practices in Asynchronous Programming文章中解释了async void
方法的工作方式以及应该避免的原因。
async void
与async Task
具有相同的语义,但异常除外。 async void
方法将捕获方法开头的当前SynchronizationContext
,并且将捕获该方法的任何异常并直接在捕获的上下文中引发。在最常见的情况下,这将导致应用程序级异常,通常是崩溃。有些人称async void
方法是“即发即忘”,但由于他们的特殊行为,我更喜欢“火灾和崩溃”。 :)
“避免异步void”是一般准则,有一个值得注意的例外:事件处理程序(或逻辑上事件处理程序的项目,例如ICommand.Execute
实现)。
它是如何工作的?这如何转化为aspnet?
它就像任何其他async
方法一样工作。主要的平台区别是,当async
方法完成时,UI线程不需要知道。 ASP.NET需要知道,因此它知道何时发送请求,但UI无需知道async
方法何时完成。所以async void
有效。它仍然是最好的避免,因为调用代码通常 需要知道它何时完成。
答案 1 :(得分:6)
Async void仅用于事件处理程序/委托可比性。 Execute是一个事件回调,可能来自DelegateCommand
或类似的。
它的工作方式是它与它的函数返回Task
完全相同,但调用者从未在返回的任务上调用await
。
在ASP.NET上,您可能永远不会使用async void,而是使用显示返回Task<ActionResult>
的方法的控制器,使用HostingEnviorment.QueueBackgroundWorkItem
或使用包含在{{{ 3}}在您在普通桌面编程中使用async void
的情况下。
public void Page_Load(object sender, EventArgs e)
{
RegisterAsyncTask(new PageAsyncTask(LoadSomeData));
}