Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

System.ObjectDisposedException while opening a connection #411

Closed
nvivo opened this issue Dec 7, 2017 · 1 comment
Closed

System.ObjectDisposedException while opening a connection #411

nvivo opened this issue Dec 7, 2017 · 1 comment
Assignees
Labels

Comments

@nvivo
Copy link

@nvivo nvivo commented Dec 7, 2017

After updating to the latest version, I started getting this error sometimes when opening a connection with OpenAsync - I'm not using SSL.

System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'SslStream'.
   at System.Net.Security.SslState.CheckThrow(Boolean authSuccessCheck, Boolean shutdownCheck)
   at System.Net.Security.SslState.get_SecureStream()
   at System.Net.Security.SslStream.Write(Byte[] buffer, Int32 offset, Int32 count)
   at MySqlConnector.Protocol.Serialization.StreamByteHandler.WriteBytesAsync(ArraySegment`1 data, IOBehavior ioBehavior)
   at MySqlConnector.Protocol.Serialization.ProtocolUtility.WritePacketAsync(IByteHandler byteHandler, Int32 sequenceNumber, ArraySegment`1 contents, IOBehavior ioBehavior)
   at MySqlConnector.Protocol.Serialization.ProtocolUtility.WritePayloadAsync(IByteHandler byteHandler, Func`1 getNextSequenceNumber, ArraySegment`1 payload, IOBehavior ioBehavior)
   at MySqlConnector.Protocol.Serialization.StandardPayloadHandler.WritePayloadAsync(ArraySegment`1 payload, IOBehavior ioBehavior)
   at MySqlConnector.Core.ServerSession.<DisposeAsync>d__55.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at MySqlConnector.Core.ConnectionPool.Return(ServerSession session)
   at MySqlConnector.Core.ServerSession.ReturnToPool()
   at MySqlConnector.Core.ConnectionPool.RecoverLeakedSessions()
   at MySqlConnector.Core.ConnectionPool.<GetSessionAsync>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at MySql.Data.MySqlClient.MySqlConnection.<CreateSessionAsync>d__77.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at MySql.Data.MySqlClient.MySqlConnection.<OpenAsync>d__19.MoveNext()

@bgrainger bgrainger added the bug label Dec 7, 2017
@bgrainger bgrainger self-assigned this Dec 7, 2017
@bgrainger
Copy link
Member

@bgrainger bgrainger commented Dec 7, 2017

It looks like this exception should be caught and ignored here; I can push a fix for that.

I'm not using SSL

The default value for the SSL Mode connection string option is Preferred, which will use SSL if the server supports it (e.g., with a self-signed certificate).

There is non-zero overhead for doing this; if you don't need a TLS-encrypted connection to your DB server, use SSL Mode=None. (And note that it's also vulnerable to a MITM attack because the certificate isn't verified.)

at MySqlConnector.Core.ConnectionPool.RecoverLeakedSessions()
at MySqlConnector.Core.ConnectionPool.<GetSessionAsync>d__3.MoveNext()

This call stack is an indicator of potential problems. When you went to open a connection, the connection pool found that all connections (i.e., Maximum Pool Size, defaults to 100) were in use. It then performed a scan of all open connections and found that some MySqlConnection objects had been garbage collected without their Close or Dispose method having been called. MySqlConnector will automatically recover from this situation (if demand is low). (If demand is high, the GC may not have run quickly enough to reclaim abandoned connections and you'll get a "connection timeout" waiting for a free connection in the pool.)

I strongly recommend putting all new MySqlConnection() calls in a using block. If you can't do that because you're using DI and your DI container is creating the objects, then I recommend reading its documentation to learn how to ensure that all IDisposable objects are disposed at the end of their lifetime. (Even in the DI scenario, one other workaround you can apply is to make sure all Open/OpenAsync calls have a corresponding call to Close; this will allow the connection to be returned to the pool.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

2 participants