如果你不将它推广到控制器,为什么要使用异步?

时间:2016-11-10 15:43:56

标签: asp.net-mvc async-await

我试图弄清楚如何在我的Asp.Net MVC中使用C#中的async / await。 主要的一点似乎是它帮助asp.net在你做IO时从工作池中释放线程(所以他们可以处理其他东西)。为此,您必须从执行IO调用的方法到控制器操作提升async / await修饰符(最好只有几层)。

在没有将async / await提升到我的控制器的情况下使用此功能有什么意义吗? (例如,在调用Async方法后添加Task.Wait。)

2 个答案:

答案 0 :(得分:2)

答案是“是”,但在动作中使用Task.Wait()并不是一个好主意,因为它可能导致死锁情况。

请参考指南中的以下内容,Async/Await Best Practice Stephen Cleary

  

图3阻止异步代码时的常见死锁问题

public static class DeadlockDemo
{
   private static async Task DelayAsync()
   {
      await Task.Delay(1000);
   }
   // This method causes a deadlock when called in a GUI or ASP.NET context.
   public static void Test()
   {
       // Start the delay.
       var delayTask = DelayAsync();
       // Wait for the delay to complete.
       delayTask.Wait();
   }
}

但是,如果您将ConfigureAwait(false)添加到DelayAsync(),请执行以下操作:

await Task.Delay(1000).ConfigureAwait(false)

然后你可以避免死锁,如文章中所述:

  

除了性能之外,ConfigureAwait还有另一个重要方面:它可以避免死锁。再次考虑图3 ;如果将“ConfigureAwait(false)”添加到DelayAsync中的代码行,则可以避免死锁。这次,当await完成时,它会尝试在线程池上下文中执行async方法的其余部分。该方法能够完成,完成其返回的任务,并且没有死锁。如果您需要逐渐将应用程序从同步转换为异步,则此技术特别有用。

答案 1 :(得分:0)

不要使用Task.Wait,因为它可能会死锁或产生AggregateException。如果您需要这样做,那么您应该使用非阻塞的Task.WhenAll

但一般来说,最安全的是端到端使用异步代码。在整个堆栈中使用异步的好处是,您的代码将更容易调试,错误处理更加简单。

所以,如果你打算使用async / await - 将它包含在你的控制器中并避免使用像Task.Wait这样的阻塞代码。