当异步操作正在进行时,不能更改连接
本文关键字:不能 连接 进行时 异步操作 | 更新日期: 2023-09-27 18:19:12
我的应用程序在一段时间内工作得很好然后突然我在每个页面上都得到了这个非常奇怪的错误,
[InvalidOperationException: Connection cannot be changed while async operation is in progress.]
System.Data.SqlClient.SqlCommand.set_Connection(SqlConnection value) +5340612
InvertedSoftware.DataBlock.<ExecuteReaderAsync>d__7.MoveNext() +679
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +93
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +52
XX.Data.Repositories.<GetAllByMerchantIdAsync>d__1f.MoveNext() in c:'Users'XX.cs:90
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +93
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +52
Namespace.Controllers.<Index>d__2.MoveNext() in c:'Users'XX.cs.cs:44
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +93
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +52
System.Web.Mvc.Async.TaskAsyncActionDescriptor.EndExecute(IAsyncResult asyncResult) +84
System.Web.Mvc.Async.<>c__DisplayClass37.<BeginInvokeAsynchronousActionMethod>b__36(IAsyncResult asyncResult) +17
System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +48
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +32
System.Web.Mvc.Async.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f() +50
System.Web.Mvc.Async.<>c__DisplayClass48.<InvokeActionMethodFilterAsynchronouslyRecursive>b__41() +225
System.Web.Mvc.Async.<>c__DisplayClass48.<InvokeActionMethodFilterAsynchronouslyRecursive>b__41() +225
System.Web.Mvc.Async.<>c__DisplayClass33.<BeginInvokeActionMethodWithFilters>b__32(IAsyncResult asyncResult) +10
System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +48
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +34
System.Web.Mvc.Async.<>c__DisplayClass2b.<BeginInvokeAction>b__1c() +26
System.Web.Mvc.Async.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult) +100
System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +48
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +27
System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +13
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +36
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +53
System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +39
System.Web.Mvc.Controller.<BeginExecute>b__15(IAsyncResult asyncResult, Controller controller) +12
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +28
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +53
System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +29
System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10
System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +21
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +36
System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +53
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +31
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
System.Web.CallHandlerExecutionStep.OnAsyncHandlerCompletion(IAsyncResult ar) +129
注意我使用MVC 5.1和Azure网站。我的Azure网站与Sql Azure对话。下面是抛出错误的代码,
using (var reader = await SqlHelper.ExecuteReaderAsync(_connectionString, CommandType.StoredProcedure, "MySP", parameters))
和我使用这个SqlHelper.cs
SqlHelper
类有一个bug。ExecuteReader(Async)
返回一个打开的读取器。它立即将用于获取该读取器的命令放回池中。这意味着现在存在一个竞争条件:读取器可以使用,而底层命令可以由另一个线程修改。这就是为什么SqlCommand.set_Connection
是投掷。
将SqlCommand
池化不是一个好主意,因为创建命令非常便宜。池中的同步可能比设置一个新命令更昂贵。