No longer unscribe from Session events in finalizer, as we wouldn't even get finalized if Session still had subscriptions for the current instance.

This commit is contained in:
drieseng
2016-05-03 21:35:57 +02:00
parent 28a1892dc2
commit dc327d7887
2 changed files with 33 additions and 70 deletions
+23 -39
View File
@@ -952,58 +952,45 @@ namespace Renci.SshNet.Channels
{
Close(false);
if (_session != null)
var session = _session;
if (session != null)
{
UnsubscribeFromSessionEvents(_session);
session.ChannelWindowAdjustReceived -= OnChannelWindowAdjust;
session.ChannelDataReceived -= OnChannelData;
session.ChannelExtendedDataReceived -= OnChannelExtendedData;
session.ChannelEofReceived -= OnChannelEof;
session.ChannelCloseReceived -= OnChannelClose;
session.ChannelRequestReceived -= OnChannelRequest;
session.ChannelSuccessReceived -= OnChannelSuccess;
session.ChannelFailureReceived -= OnChannelFailure;
session.ErrorOccured -= Session_ErrorOccured;
session.Disconnected -= Session_Disconnected;
_session = null;
}
if (_channelClosedWaitHandle != null)
var channelClosedWaitHandle = _channelClosedWaitHandle;
if (channelClosedWaitHandle != null)
{
_channelClosedWaitHandle.Dispose();
channelClosedWaitHandle.Dispose();
_channelClosedWaitHandle = null;
}
if (_channelServerWindowAdjustWaitHandle != null)
var channelServerWindowAdjustWaitHandle = _channelServerWindowAdjustWaitHandle;
if (channelServerWindowAdjustWaitHandle != null)
{
_channelServerWindowAdjustWaitHandle.Dispose();
channelServerWindowAdjustWaitHandle.Dispose();
_channelServerWindowAdjustWaitHandle = null;
}
if (_errorOccuredWaitHandle != null)
var errorOccuredWaitHandle = _errorOccuredWaitHandle;
if (errorOccuredWaitHandle != null)
{
_errorOccuredWaitHandle.Dispose();
errorOccuredWaitHandle.Dispose();
_errorOccuredWaitHandle = null;
}
_isDisposed = true;
}
else
{
UnsubscribeFromSessionEvents(_session);
}
}
/// <summary>
/// Unsubscribes the current <see cref="Channel"/> from session events.
/// </summary>
/// <param name="session">The session.</param>
/// <remarks>
/// Does nothing when <paramref name="session"/> is <c>null</c>.
/// </remarks>
private void UnsubscribeFromSessionEvents(ISession session)
{
if (session == null)
return;
session.ChannelWindowAdjustReceived -= OnChannelWindowAdjust;
session.ChannelDataReceived -= OnChannelData;
session.ChannelExtendedDataReceived -= OnChannelExtendedData;
session.ChannelEofReceived -= OnChannelEof;
session.ChannelCloseReceived -= OnChannelClose;
session.ChannelRequestReceived -= OnChannelRequest;
session.ChannelSuccessReceived -= OnChannelSuccess;
session.ChannelFailureReceived -= OnChannelFailure;
session.ErrorOccured -= Session_ErrorOccured;
session.Disconnected -= Session_Disconnected;
}
/// <summary>
@@ -1012,9 +999,6 @@ namespace Renci.SshNet.Channels
/// </summary>
~Channel()
{
// Do not re-create Dispose clean-up code here.
// Calling Dispose(false) is optimal in terms of
// readability and maintainability.
Dispose(false);
}
+10 -31
View File
@@ -16,21 +16,14 @@ namespace Renci.SshNet
/// </summary>
public class SshCommand : IDisposable
{
private readonly ISession _session;
private ISession _session;
private readonly Encoding _encoding;
private IChannelSession _channel;
private CommandAsyncResult _asyncResult;
private AsyncCallback _callback;
private EventWaitHandle _sessionErrorOccuredWaitHandle = new AutoResetEvent(false);
private EventWaitHandle _sessionErrorOccuredWaitHandle;
private Exception _exception;
private bool _hasError;
private readonly object _endExecuteLock = new object();
/// <summary>
@@ -151,6 +144,7 @@ namespace Renci.SshNet
CommandText = commandText;
_encoding = encoding;
CommandTimeout = new TimeSpan(0, 0, 0, 0, -1);
_sessionErrorOccuredWaitHandle = new AutoResetEvent(false);
_session.Disconnected += Session_Disconnected;
_session.ErrorOccured += Session_ErrorOccured;
@@ -525,22 +519,6 @@ namespace Renci.SshNet
channel.Dispose();
}
/// <summary>
/// Unsubscribes the current <see cref="SshCommand"/> from session events.
/// </summary>
/// <param name="session">The session.</param>
/// <remarks>
/// Does nothing when <paramref name="session"/> is <c>null</c>.
/// </remarks>
private void UnsubscribeFromSessionEvents(ISession session)
{
if (session == null)
return;
session.Disconnected -= Session_Disconnected;
session.ErrorOccured -= Session_ErrorOccured;
}
#region IDisposable Members
private bool _isDisposed;
@@ -567,7 +545,13 @@ namespace Renci.SshNet
{
// unsubscribe from session events to ensure other objects that we're going to dispose
// are not accessed while disposing
UnsubscribeFromSessionEvents(_session);
var session = _session;
if (session != null)
{
session.Disconnected -= Session_Disconnected;
session.ErrorOccured -= Session_ErrorOccured;
_session = null;
}
// unsubscribe from channel events to ensure other objects that we're going to dispose
// are not accessed while disposing
@@ -601,11 +585,6 @@ namespace Renci.SshNet
_isDisposed = true;
}
else
{
// avoid event-based memory leaks when client does not dispose instance
UnsubscribeFromSessionEvents(_session);
}
}
/// <summary>