System.InvalidOperationException: 无法在C# .NET中替换活动读取器

huangapple go评论74阅读模式
英文:

System.InvalidOperationException: Can't replace active reader in c# .net

问题

我的.NET 6应用程序一直在正常工作,但最近在负载增加时出现了这个错误:

System.InvalidOperationException:无法替换活动读取器

我已经对这个问题进行了很多调查,但未能找到解决方案。有人可以帮忙吗?

System.InvalidOperationException: 无法替换活动读取器。
   在 MySqlConnector.MySqlConnection.SetActiveReader(MySqlDataReader dataReader) 中的 /_/src/MySqlConnector/MySqlConnection.cs:line 874
   在 MySqlConnector.MySqlDataReader.CreateAsync(CommandListPosition commandListPosition, ICommandPayloadCreator payloadCreator, IDictionary`2 cachedProcedures, IMySqlCommand command, CommandBehavior behavior, Activity activity, IOBehavior ioBehavior, CancellationToken cancellationToken) 中的 /_/src/MySqlConnector/MySqlDataReader.cs:line 460
   在 MySqlConnector.Core.CommandExecutor.ExecuteReaderAsync(IReadOnlyList`1 commands, ICommandPayloadCreator payloadCreator, CommandBehavior behavior, Activity activity, IOBehavior ioBehavior, CancellationToken cancellationToken) 中的 /_/src/MySqlConnector/Core/CommandExecutor.cs:line 56
   在 MySqlConnector.MySqlCommand.ExecuteReaderAsync(CommandBehavior behavior, IOBehavior ioBehavior, CancellationToken cancellationToken) 中的 /_/src/MySqlConnector/MySqlCommand.cs:line 344
   在 MySqlConnector.MySqlCommand.ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken) 中的 /_/src/MySqlConnector/MySqlCommand.cs:line 337
   在 Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
   在 Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
   在 Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.InitializeReaderAsync(AsyncEnumerator enumerator, CancellationToken cancellationToken)
   在 Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.<>c__DisplayClass33_0`2.<<ExecuteAsync>b__0>d.MoveNext()
--- 上一个位置的堆栈跟踪结束 ---
   在 Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.ExecuteImplementationAsync[TState,TResult](Func`4 operation, Func`4 verifySucceeded, TState state, CancellationToken cancellationToken)
英文:

My .Net 6 application was working without any problems but recently whenever the load increases we see this error:

> System.InvalidOperationException: Can't replace active reader

I have investigated a lot on this issue , but could not find a solution. Can someone help on this please?

System.InvalidOperationException: Can't replace active reader.
   at MySqlConnector.MySqlConnection.SetActiveReader(MySqlDataReader dataReader) in /_/src/MySqlConnector/MySqlConnection.cs:line 874
   at MySqlConnector.MySqlDataReader.CreateAsync(CommandListPosition commandListPosition, ICommandPayloadCreator payloadCreator, IDictionary`2 cachedProcedures, IMySqlCommand command, CommandBehavior behavior, Activity activity, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/MySqlDataReader.cs:line 460
   at MySqlConnector.Core.CommandExecutor.ExecuteReaderAsync(IReadOnlyList`1 commands, ICommandPayloadCreator payloadCreator, CommandBehavior behavior, Activity activity, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/Core/CommandExecutor.cs:line 56
   at MySqlConnector.MySqlCommand.ExecuteReaderAsync(CommandBehavior behavior, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/MySqlCommand.cs:line 344
   at MySqlConnector.MySqlCommand.ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/MySqlCommand.cs:line 337
   at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.InitializeReaderAsync(AsyncEnumerator enumerator, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.<>c__DisplayClass33_0`2.<<ExecuteAsync>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.ExecuteImplementationAsync[TState,TResult](Func`4 operation, Func`4 verifySucceeded, TState state, CancellationToken cancellationToken)

答案1

得分: 1

这里提供的信息远远不足以准确诊断问题。然而,我见过三种常见问题导致类似行为:

  1. 应用程序使用数据访问模式,尝试在整个应用程序中保留相同的连接对象。这是一个不好的做法。每个查询应该获得自己的新连接对象。最好的情况是使用 using 块创建连接。
  2. 应用程序调用 connection.Close() 而不是在 try 块之后的 finally 部分或使用 using 块的一部分来处理连接的释放。这可能会导致连接在发生异常时(甚至是已处理的异常)仍然保持打开状态,而在负载较重的情况下,这些挂起的连接可能会耗尽客户端或服务器上的连接池。同样,解决方案是使用 using 块。
  3. 您已经在其他方面做得很对,但负载确实非常高,以至于连接池从正常使用中耗尽(这是非常罕见的!)。在这种情况下,解决方案是更积极地延迟打开 using 块并更早地关闭它们,开始更有效地处理连接(即:可以在相同的 Execute__() 调用中运行多个 SQL 语句),并探索调整池大小。

我知道错误消息引用的是读取器而不是连接,但所有这些情况都可能导致尝试在另一个读取器仍然活动的连接上运行新查询并将结果与连接关联,因为池中的先前连接未完成。但再次强调:问题描述中提供的信息远远不足以准确诊断问题。

英文:

There's not even close to enough info here to accurately diagnose this. However, I've seen three common issues causing similar behavior:

  1. The app uses a data access pattern that tries to preserve the same connection object throughout the app. This is a bad idea. Each query should get it's own new connection object. Really. Ideally the connection will be created with a using block.
  2. The app calls connection.Close() instead of disposing connections as part of a finally section after a try block or with a using block. This potentially leaves connections hanging open when there are exceptions (possibly even handled exceptions), and under load these hanging connections can exhaust the connection pool on either the clients or the server. Again, the solution is using blocks.
  3. You're already doing the other things right, but the load really is so high the connection pool is becoming exhausted just from normal use (this is extremely rare!). In that case, the solution is to be even more aggressive with opening the using blocks later and closing them earlier, start being more efficient with the connections (ie: you can run more than one SQL statement in the same Execute__() call), and explore adjusting the pool size.

I know the error message references a reader rather than a connection, but all of these can lead to trying to run a new query and associate the result with a connection while another reader on the connection is still active, because a prior connection in the pool wasn't finished. But again: there's nothing like enough info in the question to accurately diagnose this.

huangapple
  • 本文由 发表于 2023年7月27日 22:53:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/76780982.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定