这有效
我有一个非常奇怪的问题正在发生。 我收到来自 API 调用的错误There is already an open DataReader associated with this Command which must be closed first.
。 但是,此错误仅发生在这一个服务器上,而不是同时容纳数据库的主服务器上。
代码是精确的,web.config 是相同的,除了在主服务器上使用 localhost 的连接字符串。
此 API 调用使用会话 Cookie 属性来验证用户。 这是 asp.net 成员在这里发生的唯一独特事情。
唯一不同的是服务器错误关闭了TLS 1.0,但主服务器没有。 我也不想启用MultipleActiveResultSets
因为这以前总是有效的。 任何帮助都会很棒。
https://example.com/api/v1/test/help?testid=109178&_COOKIE_=<cookie>
在下面的 Get 方法的操作上装饰的此过滤器上进行一些日志记录。
这是在 MVC 操作筛选器中。
var user = Membership.GetUser();
if (user != null)
{
if (Roles.IsUserInRole(RoleName.ScoreKeeper.ToString()))
{
var memberId = _apiAuthenticationService.ValidUser(new Guid(user.ProviderUserKey.ToString()));
if (memberId > 0)
{
apiAuthorizeRequest.MemberId = memberId;
return true;
}
}
}
public int ValidUser(Guid userId)
{
var apiMember = _membersRepository.Get(null, q => q.UserId == userId);
if (apiMember != null)
return apiMember.Id;
return 0;
}
堆栈跟踪
Stack Trace : at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)
at System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlan.Execute[TResultType](ObjectContext context, ObjectParameterCollection parameterValues)
at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClass7.<GetResults>b__5()
at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation)
at System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<System.Collections.Generic.IEnumerable<T>.GetEnumerator>b__0()
at System.Data.Entity.Internal.LazyEnumerator`1.MoveNext()
at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source)
at Tournaments.Data.Repositories.RepositoryBase`1.Get(Expression`1[] includes, Expression`1 where) in D:ProjectsTournaments.DataRepositoriesRepositoryBase.cs:line 110
at Tournaments.Services.Api.ApiAuthenticationService.ValidUser(Guid userId) in D:ApiApiAuthenticationService.cs:line 116
内部异常
Message :There is already an open DataReader associated with this Command which must be closed first. Source :System.Data Stack Trace : at System.Data.SqlClient.SqlInternalConnectionTds.ValidateConnectionForExecute(SqlCommand command) at System.Data.SqlClient.SqlCommand.ValidateCommand(String method, Boolean async) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed) at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand command, DbCommandInterceptionContext interceptionContext) at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior) TargetSite :Void ValidateConnectionForExecute(System.Data.SqlClient.SqlCommand)
这是一个并发问题;ActionFilterAttribute
被视为单一实例,因此单个实例处理所有请求。
因此,多个并发请求共享同一个_apiAuthenticationService
实例,该实例保存DbContext
。这会导致同时在共享DbContext
实例上执行同时执行查询/命令的可能性,该实例因给定的异常而失败。
您看到此错误的时间和频率取决于 Web 请求的流量以及DbContext
/database 执行查询/命令的速度。
(该 TLS 错误可能已经导致一些延迟。
解决方案:不要在ActionFilter
中使用共享状态;为每个请求单独解析/实例化依赖项。