|
|
@@ -14,7 +14,7 @@ namespace Renci.SshNet
|
|
|
/// <summary>
|
|
|
/// Contains operation for working with SSH Shell.
|
|
|
/// </summary>
|
|
|
- public partial class ShellStream : Stream
|
|
|
+ public class ShellStream : Stream
|
|
|
{
|
|
|
private const string CrLf = "\r\n";
|
|
|
private const int BufferSize = 1024;
|
|
|
@@ -25,6 +25,7 @@ namespace Renci.SshNet
|
|
|
private readonly Queue<byte> _outgoing;
|
|
|
private IChannelSession _channel;
|
|
|
private AutoResetEvent _dataReceived = new AutoResetEvent(false);
|
|
|
+ private bool _isDisposed;
|
|
|
|
|
|
/// <summary>
|
|
|
/// Occurs when data was received.
|
|
|
@@ -667,27 +668,51 @@ namespace Renci.SshNet
|
|
|
{
|
|
|
base.Dispose(disposing);
|
|
|
|
|
|
- if (_session != null)
|
|
|
- {
|
|
|
- _session.Disconnected -= Session_Disconnected;
|
|
|
- _session.ErrorOccured -= Session_ErrorOccured;
|
|
|
- }
|
|
|
+ if (_isDisposed)
|
|
|
+ return;
|
|
|
|
|
|
- if (_channel != null)
|
|
|
+ if (disposing)
|
|
|
{
|
|
|
- _channel.DataReceived -= Channel_DataReceived;
|
|
|
- _channel.Closed -= Channel_Closed;
|
|
|
- _channel.Dispose();
|
|
|
- _channel = null;
|
|
|
- }
|
|
|
+ UnsubscribeFromSessionEvents(_session);
|
|
|
|
|
|
- if (_dataReceived != null)
|
|
|
+ if (_channel != null)
|
|
|
+ {
|
|
|
+ _channel.DataReceived -= Channel_DataReceived;
|
|
|
+ _channel.Closed -= Channel_Closed;
|
|
|
+ _channel.Dispose();
|
|
|
+ _channel = null;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (_dataReceived != null)
|
|
|
+ {
|
|
|
+ _dataReceived.Dispose();
|
|
|
+ _dataReceived = null;
|
|
|
+ }
|
|
|
+
|
|
|
+ _isDisposed = true;
|
|
|
+ }
|
|
|
+ else
|
|
|
{
|
|
|
- _dataReceived.Dispose();
|
|
|
- _dataReceived = null;
|
|
|
+ UnsubscribeFromSessionEvents(_session);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /// <summary>
|
|
|
+ /// Unsubscribes the current <see cref="Shell"/> 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;
|
|
|
+ }
|
|
|
+
|
|
|
private void Session_ErrorOccured(object sender, ExceptionEventArgs e)
|
|
|
{
|
|
|
OnRaiseError(e);
|