如果不将其提升到控制器,为什么要使用异步?

问题描述 投票:1回答:2

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

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

asp.net-mvc async-await
2个回答
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方法的其余部分。该方法能够完成,完成其返回的任务,并且没有死锁。如果您需要逐渐将应用程序从同步转换为异步,则此技术特别有用。


0
投票

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.