DbConnection.Open()有效,但dbConnection.OpenAsync()不起作用

Lui*_*rao 2 .net sql-server asp.net-mvc asynchronous

这是困难的一个.使用完全相同的查询字符串,完全相同的以下代码:

using (var db = new SqlConnection(queryString))
{
   await db.OpenAsync();
   var results = await db.ExecuteSomethingAsync...;
   db.Close();
{
Run Code Online (Sandbox Code Playgroud)

从Windows应用程序运行时将工作.然而,await OpenAsync()当从IIS Express或IIS 7运行时,它将永远陷入困境.如果我用db.Open()它替换那条线就行了.有什么建议?

Mar*_*ell 6

await需要在ASP.NET中谨慎对待,因为同步上下文想要为单个请求序列化工作.您发布的代码本身可能很好 - await不会阻止.但是,我希望在调用链中的某个地方,你正在调用.Wait()或访问.Result,而不是await.

这里有几个选项:

  • 不使用.Wait().Result(或类似)在所有 -相反,只使用await,使之正确异步操作
  • 或者,.ConfigureAwait(false)用来告诉它忽略同步上下文; 不幸的是,这需要添加到你所有的地方await,即

    await db.OpenAsync().ConfigureAwait(false);
    var results = await db.ExecuteSomethingAsync(...).ConfigureAwait(false);
    
    Run Code Online (Sandbox Code Playgroud)
  • 或者,只使用同步代码 - 在大多数情况下,sql将非常快速地运行- 因此推送异步并不一定像你想象的那样帮助; 显然这可能因使用情况而异; 但要记住的一个关键点是ASP.NET已经具有固有的线程 - 这并不是说整个服务器在这里停止运行


Ste*_*ary 5

正如其他人所提到的,首先要确保您没有WaitResult调用您的层次结构.一系列async方法在一个依赖于框架的入口点结束.在UI/WebForms应用程序中,这通常是一个async void事件处理程序.在WebAPI/MVC应用程序中,这通常是一个async操作.

要检查ASP.NET的另外两件事是:

  • 确保您的目标平台是.NET 4.5.
  • 确保您已UseTaskFriendlySynchronizationContext设置为true.

如果您需要async在多个平台上的共享库中提供支持,您可能会发现Microsoft.Bcl.AsyncNuGet库很有帮助.