-
Type: Improvement
-
Resolution: Done
-
Priority: Minor - P4
-
Affects Version/s: 1.0
-
Component/s: None
-
None
MongoConnection.tcpClient might be not connected in MongoConnection.Close() leading to a handled InvalidOperationException (I encountered this when simulating reading from a replica set, shutting down primary member in the process). While this does not affect functionality, debugging (especially online) and performance suffers from extra exceptions.
Looks like TcpClient.GetNetworkStream() throws an exception instead of returning null if it's not connected, so checking TcpClient.Connected before trying to get the stream (actually around entire first try/catch block in MongoConnection.Close()) would be nice to prevent that extra exception.
I also don't think that casting the TcpClient to IDisposable and calling Dispose(), along with closing the stream explicitly is necessary, because TcpClient.Close() calls Dispose() internally.
I've seen the following: "// note: TcpClient.Close doesn't close the NetworkStream!?" – this does not seem to be the case.
The following is partial output from Red Gate Reflector utility on certainl BCL methods from .NET 4:
public void TcpClient.Close()
{
if (Logging.On)
((IDisposable) this).Dispose();
if (Logging.On)
}
void TcpClient.IDisposable.Dispose()
{
this.Dispose(true);
}
protected virtual void TcpClient.Dispose(bool disposing)
{
if (Logging.On)
if (this.m_CleanedUp)
{
if (Logging.On)
}
else
{
if (disposing)
{
IDisposable dataStream = this.m_DataStream;
if (dataStream != null)
{ dataStream.Dispose(); }
else
{
Socket client = this.Client;
if (client != null)
{
try
{ client.InternalShutdown(SocketShutdown.Both); }
finally
{ client.Close(); this.Client = null; }
}
}
GC.SuppressFinalize(this);
}
this.m_CleanedUp = true;
if (Logging.On)
{ Logging.Exit(Logging.Sockets, this, "Dispose", ""); }
}
}
public void Stream.Dispose()
{
this.Close();
}
public virtual void Stream.Close()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
Neither Stream.Close() nor Stream.Dispose() are overriden in NetworkStream (only Dispose(bool) does, but it doesn't matter).
This is also related to http://jira.mongodb.org/browse/CSHARP-150