c#如何处理异步void

时间:2017-01-16 21:55:04

标签: c# async-await

我通常对网络服务器进行编程,起初我认为必须有连续的方法链来返回任务,所以堆栈中的内容可能会询问数据库是否完成。

最近我看到了wpf代码,它做了类似的事情:

    public async void Execute(object parameter)
    {
        await ExecuteAsync(parameter);
    }

在事件处理程序中调用。 UI似乎是响应式的,所以我猜它确实有效。它是如何工作的?这如何转化为aspnet?

2 个答案:

答案 0 :(得分:8)

我在Best Practices in Asynchronous Programming文章中解释了async void方法的工作方式以及应该避免的原因。

async voidasync 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));
}