diff --git a/src/Renci.SshNet/Channels/Channel.cs b/src/Renci.SshNet/Channels/Channel.cs
index 04dcefb4..322cdde5 100644
--- a/src/Renci.SshNet/Channels/Channel.cs
+++ b/src/Renci.SshNet/Channels/Channel.cs
@@ -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);
- }
- }
-
- ///
- /// Unsubscribes the current from session events.
- ///
- /// The session.
- ///
- /// Does nothing when is null.
- ///
- 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;
}
///
@@ -1012,9 +999,6 @@ namespace Renci.SshNet.Channels
///
~Channel()
{
- // Do not re-create Dispose clean-up code here.
- // Calling Dispose(false) is optimal in terms of
- // readability and maintainability.
Dispose(false);
}
diff --git a/src/Renci.SshNet/SshCommand.cs b/src/Renci.SshNet/SshCommand.cs
index 87072425..7aa94896 100644
--- a/src/Renci.SshNet/SshCommand.cs
+++ b/src/Renci.SshNet/SshCommand.cs
@@ -16,21 +16,14 @@ namespace Renci.SshNet
///
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();
///
@@ -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();
}
- ///
- /// Unsubscribes the current from session events.
- ///
- /// The session.
- ///
- /// Does nothing when is null.
- ///
- 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);
- }
}
///