Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net ExecuteReaderAsync任务挂起/持续等待激活_.net - Fatal编程技术网

.net ExecuteReaderAsync任务挂起/持续等待激活

.net ExecuteReaderAsync任务挂起/持续等待激活,.net,.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

我有以下程序,看起来很简单,但只是持续等待,没有超时:

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=wait Command.ExecuteReaderAsync行并挂起

如果我将该行替换为以下内容:

Dim t = Command.ExecuteReaderAsync
Reader = Await t
在等待时中断,我可以看到task t的状态为WaitingForActivation。我还可以在SQL探查器上看到读取器调用的SP已正确执行

现在来看奇怪的部分——如果我添加一个thread.sleep 10毫秒,然后看看t,任务的状态是RunToCompletion,而且世界上一切都很好

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

我很愿意接受我做错了什么(通常是这样的…),但我不知道在这种情况下会发生什么。

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

解决方案是通过以下方式将ConfigureWait应用于任务:

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

我正在从MySql迁移到SQL Server-MySql异步命令似乎不存在同样的问题,也不需要ConfigureWait。

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

解决方案是通过以下方式将ConfigureWait应用于任务:

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

我正在从MySql迁移到SQL Server-MySql异步命令似乎没有出现相同的问题,也不需要ConfigureWait。

我打赌MySql命令没有出现这个问题,因为它们实际上不是异步的。我已经见过很多次了——只是做了相当于
return Task.FromResult(ExecuteReader())。还请注意,如果任务在返回之前就完成了,则可以同步返回任务。我在HttpClient.GetAsync中看到过这种情况,在流式I/O中也经常发生。感谢您的链接。不必到处使用ConfigureAwait(false),您可以像链接中提到的那样重构代码以实现异步—这将解决问题,而无需到处复制粘贴代码。当然,您可能需要重构大量代码,因此可能不可能在所有情况下都进行重构。完全异步的能力取决于您所编写的代码-老式的WebApi或控制台项目不能异步(我知道c#现在支持这一点,但还没有看到vb.net支持发布).我打赌MySQL命令不会出现这个问题,因为它们实际上不是异步的。我已经见过很多次了——只是做了相当于
return Task.FromResult(ExecuteReader())。还请注意,如果任务在返回之前就完成了,则可以同步返回任务。我在HttpClient.GetAsync中看到过这种情况,在流式I/O中也经常发生。感谢您的链接。不必到处使用ConfigureAwait(false),您可以像链接中提到的那样重构代码以实现异步—这将解决问题,而无需到处复制粘贴代码。当然,您可能需要重构大量代码,因此可能不可能在所有情况下都进行重构。完全异步的能力取决于您所编写的代码-老式的WebApi或控制台项目不能异步(我知道c#现在支持这一点,但还没有看到vb.net支持发布)。