mirror of
https://github.com/sshnet/SSH.NET.git
synced 2026-09-10 17:25:51 +00:00
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:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user