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