我通常编写web服务器,起初我认为必须有连续的方法链返回任务,所以填满堆栈可能会询问数据库是否完成。c#如何处理异步void
最近我看到WPF的代码,这不类似的东西:
public async void Execute(object parameter)
{
await ExecuteAsync(parameter);
}
在事件处理函数调用。用户界面似乎是响应式的,所以我想它确实有效。它是如何工作的?这是如何转化为aspnet的?
我通常编写web服务器,起初我认为必须有连续的方法链返回任务,所以填满堆栈可能会询问数据库是否完成。c#如何处理异步void
最近我看到WPF的代码,这不类似的东西:
public async void Execute(object parameter)
{
await ExecuteAsync(parameter);
}
在事件处理函数调用。用户界面似乎是响应式的,所以我想它确实有效。它是如何工作的?这是如何转化为aspnet的?
Async void仅用于事件处理程序/委托可比性。 Execute是一个事件回调,可能来自DelegateCommand
或类似的事件。
它的工作方式是,它的处理方式与您返回Task
的函数完全相同,但调用者从未在返回的任务上调用await
。
在ASP.NET你可能永远不会使用异步无效,改为使用控制器,公开方法返回一个Task<ActionResult>
,使用HostingEnviorment.QueueBackgroundWorkItem
,或者使用在在一个情况,其中Page.RegisterAsyncTask
你会使用async void
包裹起来功能在正常的桌面编程中。
public void Page_Load(object sender, EventArgs e)
{
RegisterAsyncTask(new PageAsyncTask(LoadSomeData));
}
我解释async void
方法的工作原理 - 以及为什么他们应该避免 - 在我Best Practices in Asynchronous Programming文章。
async void
与async Task
具有相同的语义,例外情况除外。一个async void
方法将在该方法开始时捕获当前的SynchronizationContext
,并且该方法的任何异常都将被捕获并直接在该捕获的上下文中引发。在最常见的情况下,这会导致应用程序级异常,通常是崩溃。有些人称async void
方法为“即忘即忘”,但由于其特殊的行为,我更喜欢“火灾和碰撞”。 :)
“避免异步无效”是一般准则,有一个值得注意的例外:事件处理程序(或逻辑上是事件处理程序的项目,如ICommand.Execute
实现)。
它是如何工作的?这是如何转化为aspnet的?
它的工作方式与其他async
方法一样。主要的平台区别在于当async
方法完成时,UI线程不需要知道。 ASP.NET需要知道它知道何时发送请求,但UI不需要知道方法何时完成。所以async void
的作品。这仍然是最好的避免,因为调用代码通常确实需要知道它何时完成。
当我不等待任务时会发生什么? – user2029276
@ user2029276 asp.net子系统不知道该任务,并可能在该功能完成执行之前拆除该网站的应用程序域,导致您告诉该功能做的工作丢失并且从未完成。你可以在WPF中摆脱这种情况的原因是你的AppDomain在用户使用这个程序的时候不会被随意拆除,只要程序运行在AppDomain上。一个不活跃的用户在一个asp.net网站上可能会有一个AppDomain被拆除,甚至没有注意到它发生。 –