我通常对web服务器进行编程,起初我认为必须有连续的方法链来返回任务,所以堆栈中的内容可能会询问数据库是否完成.
最近我看到了wpf代码,它做了类似的事情:
public async void Execute(object parameter)
{
await ExecuteAsync(parameter);
}
Run Code Online (Sandbox Code Playgroud)
在事件处理程序中调用.UI似乎是响应式的,所以我猜它确实有效.它是如何工作的?这如何转化为aspnet?
我在"异步编程最佳实践"一文中解释了async void方法的工作方式以及应该避免的原因.
async voidasync Task除了异常之外,它具有相同的语义.一种async void方法将捕获当前SynchronizationContext在方法的开始,并从该方法的任何异常将被捕获,并直接对拍摄的背景下提出.在最常见的情况下,这将导致应用程序级异常,通常是崩溃.有些人称之为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<ActionResult>,使用HostingEnviorment.QueueBackgroundWorkItem或使用函数的控制器,这些函数包含Page.RegisterAsyncTask在您async void在普通桌面编程中使用的情况中.
public void Page_Load(object sender, EventArgs e)
{
RegisterAsyncTask(new PageAsyncTask(LoadSomeData));
}
Run Code Online (Sandbox Code Playgroud)