.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支持发布)。