ExecuteReaderAsync任务挂起/持续WaitingForActivation

时间:2015-11-24 08:45:32

标签: .net

我有以下程序似乎很简单,但只是在没有超时的情况下连续等待:

Public Overrides Async Function ExecuteReaderAsync() As Task(Of Boolean)
    If Not IsNothing(Command) Then 'Command is a the standard SqlCommand object
        If Not IsNothing(Command.Connection) Then
            Try
                ExecutionFailed = True
                Command.Connection.Open()
                Reader = Await Command.ExecuteReaderAsync
                IsExecuted = True
                ExecutionFailed = False
                Return True
            Catch ex As Exception
                Debugger.Break()
            End Try
        End If
    End If

    Return False
End Function

上面的代码执行Reader = Await Command.ExecuteReaderAsync行并挂起。

如果我用这些替换该行:

Dim t = Command.ExecuteReaderAsync
Reader = Await t

并在等待中断,我可以看到任务t的状态为WaitingForActivation。我还可以在SQL事件探查器上看到读者正在调用的SP已正确执行。

现在对于奇怪的部分 - 如果我添加一个thread.sleep 10ms,然后看看t,该任务将RunToCompletion作为其状态,并且一切都在世界上。

Dim t = Command.ExecuteReaderAsync
System.Threading.Thread.Sleep(10)
Reader = Await t

我非常愿意接受我做错了什么(通常是这种情况......)但我不知道在这种情况下是什么。

1 个答案:

答案 0 :(得分:4)

答案是与上下文有关,我的代码导致死锁。这个页面对我非常有帮助,并提供了有关死锁发生原因的完整解释:

Don't Block on Async Code - Stephen Cleary

解决方案是以下列方式将ConfigureAwait应用于任务:

Await Command.Connection.OpenAsync.ConfigureAwait(False)
Reader = Await Command.ExecuteReaderAsync.ConfigureAwait(False)

我正在从MySql迁移到SQL Server - MySql async命令似乎没有出现同样的问题而且不需要ConfigureAwait。