소스 검색

Send SSH_MSG_CHANNEL_EOF and SSH_MSG_CHANNEL_CLOSE in synchronized block.
Fixes issue #84.

Eliminate public Close() method and its use within SSH.NET.
Remove wait bool from protected Close(bool) method.
The protected Close() method will now always wait for a SSH_MSG_CHANNEL_CLOSE if the client initiated closing the channel.

drieseng 9 년 전
부모
커밋
1d6177fceb
90개의 변경된 파일283개의 추가작업 그리고 508개의 파일을 삭제
  1. 2 2
      src/Renci.SshNet.Tests/Classes/Channels/ChannelDirectTcpipTest.cs
  2. 2 2
      src/Renci.SshNet.Tests/Classes/Channels/ChannelDirectTcpipTest_Dispose_SessionIsConnectedAndChannelIsOpen.cs
  3. 2 2
      src/Renci.SshNet.Tests/Classes/Channels/ChannelForwardedTcpipTest_Dispose_SessionIsConnectedAndChannelIsOpen.cs
  4. 3 3
      src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_Disposed.cs
  5. 2 2
      src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_SendChannelCloseMessageFailure.cs
  6. 8 4
      src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_SendChannelCloseMessageSuccess.cs
  7. 2 2
      src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseReceived_SendChannelCloseMessageFailure.cs
  8. 8 4
      src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseReceived_SendChannelCloseMessageSuccess.cs
  9. 2 2
      src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelEofReceived_SendChannelCloseMessageFailure.cs
  10. 2 2
      src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelEofReceived_SendChannelCloseMessageSuccess.cs
  11. 2 2
      src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived.cs
  12. 2 2
      src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived_SendChannelEofMessageFailure.cs
  13. 2 2
      src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived.cs
  14. 2 2
      src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_ChannelCloseReceived.cs
  15. 2 2
      src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived.cs
  16. 1 1
      src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Disposed_Closed.cs
  17. 6 2
      src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_OnSessionChannelCloseReceived_SessionIsConnectedAndChannelIsOpen.cs
  18. 2 2
      src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsNotOpen.cs
  19. 2 2
      src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofNotReceived.cs
  20. 2 2
      src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofNotReceived_SendEofInvoked.cs
  21. 2 2
      src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofReceived.cs
  22. 2 2
      src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsNotConnectedAndChannelIsNotOpen.cs
  23. 2 2
      src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsNotConnectedAndChannelIsOpen.cs
  24. 2 2
      src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelCloseReceived_OnClose_Exception.cs
  25. 11 5
      src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelCloseReceived_SessionIsConnectedAndChannelIsOpen_EofNotReceived.cs
  26. 11 5
      src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelCloseReceived_SessionIsConnectedAndChannelIsOpen_EofReceived.cs
  27. 2 20
      src/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Dispose_PortStarted_ChannelBound.cs
  28. 0 7
      src/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Dispose_PortStarted_ChannelNotBound.cs
  29. 4 10
      src/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_SessionErrorOccurred_ChannelBound.cs
  30. 2 22
      src/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Started_SocketSendShutdownImmediately.cs
  31. 2 22
      src/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Started_SocketVersionNotSupported.cs
  32. 0 7
      src/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Stop_PortStarted_ChannelBound.cs
  33. 0 7
      src/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Stop_PortStarted_ChannelNotBound.cs
  34. 0 7
      src/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Dispose_PortStarted_ChannelBound.cs
  35. 0 1
      src/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Start_PortNeverStarted.cs
  36. 4 5
      src/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Start_PortStarted.cs
  37. 0 1
      src/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Start_PortStopped.cs
  38. 0 7
      src/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Stop_PortStarted_ChannelBound.cs
  39. 0 7
      src/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Dispose_PortStarted_ChannelBound.cs
  40. 0 2
      src/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Start_PortNeverStarted.cs
  41. 0 2
      src/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Start_PortStarted.cs
  42. 3 5
      src/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Start_PortStopped.cs
  43. 0 2
      src/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Started.cs
  44. 0 6
      src/Renci.SshNet.Tests/Classes/ScpClientTest_Upload_FileInfoAndPath_SendExecRequestReturnsFalse.cs
  45. 0 7
      src/Renci.SshNet.Tests/Classes/ScpClientTest_Upload_FileInfoAndPath_Success.cs
  46. 2 1
      src/Renci.SshNet.Tests/Classes/SessionTest_Connected_ConnectionReset.cs
  47. 2 1
      src/Renci.SshNet.Tests/Classes/SessionTest_Connected_ServerSendsBadPacket.cs
  48. 2 1
      src/Renci.SshNet.Tests/Classes/SessionTest_Connected_ServerShutsDownSendAfterSendingIncompletePacket.cs
  49. 2 1
      src/Renci.SshNet.Tests/Classes/SessionTest_Connected_ServerShutsDownSocket.cs
  50. 1 1
      src/Renci.SshNet.Tests/Classes/SshClientTest.cs
  51. 0 2
      src/Renci.SshNet.Tests/Classes/SshCommandTest_BeginExecute_EndExecuteInvokedOnAsyncResultFromPreviousInvocation.cs
  52. 1 4
      src/Renci.SshNet.Tests/Classes/SshCommandTest_EndExecute.cs
  53. 0 8
      src/Renci.SshNet.Tests/Classes/SshCommandTest_EndExecute_ChannelOpen.cs
  54. 0 6
      src/Renci.SshNet.Tests/Classes/SubsystemSession_Connect_Connected.cs
  55. 1 14
      src/Renci.SshNet.Tests/Classes/SubsystemSession_Connect_Disconnected.cs
  56. 0 7
      src/Renci.SshNet.Tests/Classes/SubsystemSession_Disconnect_Connected.cs
  57. 0 7
      src/Renci.SshNet.Tests/Classes/SubsystemSession_Disconnect_Disposed.cs
  58. 0 7
      src/Renci.SshNet.Tests/Classes/SubsystemSession_Dispose_Connected.cs
  59. 0 7
      src/Renci.SshNet.Tests/Classes/SubsystemSession_Dispose_Disconnected.cs
  60. 0 7
      src/Renci.SshNet.Tests/Classes/SubsystemSession_Dispose_Disposed.cs
  61. 0 6
      src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelDataReceived_Connected.cs
  62. 0 1
      src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelDataReceived_Disposed.cs
  63. 3 2
      src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelDataReceived_OnDataReceived_Exception.cs
  64. 3 8
      src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelException_Connected.cs
  65. 0 1
      src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelException_Disposed.cs
  66. 0 6
      src/Renci.SshNet.Tests/Classes/SubsystemSession_OnSessionDisconnected_Connected.cs
  67. 0 1
      src/Renci.SshNet.Tests/Classes/SubsystemSession_OnSessionDisconnected_Disposed.cs
  68. 3 8
      src/Renci.SshNet.Tests/Classes/SubsystemSession_OnSessionErrorOccurred_Connected.cs
  69. 0 1
      src/Renci.SshNet.Tests/Classes/SubsystemSession_OnSessionErrorOccurred_Disposed.cs
  70. 0 1
      src/Renci.SshNet.Tests/Classes/SubsystemSession_SendData_Disposed.cs
  71. 20 0
      src/Renci.SshNet.Tests/Common/Extensions.cs
  72. 21 20
      src/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj
  73. 65 86
      src/Renci.SshNet/Channels/Channel.cs
  74. 4 6
      src/Renci.SshNet/Channels/ChannelDirectTcpip.cs
  75. 3 5
      src/Renci.SshNet/Channels/ChannelForwardedTcpip.cs
  76. 2 15
      src/Renci.SshNet/Channels/ChannelSession.cs
  77. 0 5
      src/Renci.SshNet/Channels/IChannel.cs
  78. 0 5
      src/Renci.SshNet/Channels/IChannelDirectTcpip.cs
  79. 0 5
      src/Renci.SshNet/Channels/IChannelForwardedTcpip.cs
  80. 6 13
      src/Renci.SshNet/ForwardedPortDynamic.NET.cs
  81. 0 1
      src/Renci.SshNet/ForwardedPortLocal.NET.cs
  82. 0 1
      src/Renci.SshNet/ForwardedPortRemote.cs
  83. 15 0
      src/Renci.SshNet/ISession.cs
  84. 0 8
      src/Renci.SshNet/ScpClient.NET.cs
  85. 0 4
      src/Renci.SshNet/ScpClient.cs
  86. 20 2
      src/Renci.SshNet/Session.cs
  87. 2 6
      src/Renci.SshNet/Shell.cs
  88. 1 1
      src/Renci.SshNet/ShellStream.cs
  89. 1 6
      src/Renci.SshNet/SshCommand.cs
  90. 0 1
      src/Renci.SshNet/SubsystemSession.cs

+ 2 - 2
src/Renci.SshNet.Tests/Classes/Channels/ChannelDirectTcpipTest.cs

@@ -195,7 +195,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
                             _localPacketSize);
                         channel.Open(_remoteHost, _port, _forwardedPortMock.Object, socket);
                         channel.Bind();
-                        channel.Close();
+                        channel.Dispose();
 
                         handler = socket;
 
@@ -215,7 +215,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
                 _sessionMock.Verify(p => p.TrySendMessage(It.IsAny<ChannelEofMessage>()), Times.Once);
                 _sessionMock.Verify(p => p.TrySendMessage(It.IsAny<ChannelCloseMessage>()), Times.Once);
 
-                channel.Close();
+                channel.Dispose();
 
                 _sessionMock.Verify(p => p.TrySendMessage(It.IsAny<ChannelEofMessage>()), Times.Once);
                 _sessionMock.Verify(p => p.TrySendMessage(It.IsAny<ChannelCloseMessage>()), Times.Once);

+ 2 - 2
src/Renci.SshNet.Tests/Classes/Channels/ChannelDirectTcpipTest_Close_SessionIsConnectedAndChannelIsOpen.cs → src/Renci.SshNet.Tests/Classes/Channels/ChannelDirectTcpipTest_Dispose_SessionIsConnectedAndChannelIsOpen.cs

@@ -12,7 +12,7 @@ using Renci.SshNet.Tests.Common;
 namespace Renci.SshNet.Tests.Classes.Channels
 {
     [TestClass]
-    public class ChannelDirectTcpipTest_Close_SessionIsConnectedAndChannelIsOpen
+    public class ChannelDirectTcpipTest_Dispose_SessionIsConnectedAndChannelIsOpen
     {
         private Mock<ISession> _sessionMock;
         private Mock<IForwardedPort> _forwardedPortMock;
@@ -165,7 +165,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
         {
             if (_channel != null)
             {
-                _channel.Close();
+                _channel.Dispose();
             }
         }
 

+ 2 - 2
src/Renci.SshNet.Tests/Classes/Channels/ChannelForwardedTcpipTest_Close_SessionIsConnectedAndChannelIsOpen.cs → src/Renci.SshNet.Tests/Classes/Channels/ChannelForwardedTcpipTest_Dispose_SessionIsConnectedAndChannelIsOpen.cs

@@ -13,7 +13,7 @@ using Renci.SshNet.Tests.Common;
 namespace Renci.SshNet.Tests.Classes.Channels
 {
     [TestClass]
-    public class ChannelForwardedTcpipTest_Close_SessionIsConnectedAndChannelIsOpen
+    public class ChannelForwardedTcpipTest_Dispose_SessionIsConnectedAndChannelIsOpen
     {
         private Mock<ISession> _sessionMock;
         private Mock<IForwardedPort> _forwardedPortMock;
@@ -157,7 +157,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
 
         private void Act()
         {
-            _channel.Close();
+            _channel.Dispose();
         }
 
         [TestMethod]

+ 3 - 3
src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Close_Closed.cs → src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_Disposed.cs

@@ -10,7 +10,7 @@ using Renci.SshNet.Messages.Connection;
 namespace Renci.SshNet.Tests.Classes.Channels
 {
     [TestClass]
-    public class ChannelSessionTest_Close_Closed
+    public class ChannelSessionTest_Dispose_Disposed
     {
         private Mock<ISession> _sessionMock;
         private Mock<IConnectionInfo> _connectionInfoMock;
@@ -97,12 +97,12 @@ namespace Renci.SshNet.Tests.Classes.Channels
             _channel.Closed += (sender, args) => _channelClosedRegister.Add(args);
             _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args);
             _channel.Open();
-            _channel.Close();
+            _channel.Dispose();
         }
 
         protected virtual void Act()
         {
-            _channel.Close();
+            _channel.Dispose();
         }
 
         internal ChannelSession Channel

+ 2 - 2
src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Close_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_SendChannelCloseMessageFailure.cs → src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_SendChannelCloseMessageFailure.cs

@@ -10,7 +10,7 @@ using Renci.SshNet.Messages.Connection;
 namespace Renci.SshNet.Tests.Classes.Channels
 {
     [TestClass]
-    public class ChannelSessionTest_Close_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_SendChannelCloseMessageFailure
+    public class ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_SendChannelCloseMessageFailure
     {
         private Mock<ISession> _sessionMock;
         private uint _localChannelNumber;
@@ -100,7 +100,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
 
         private void Act()
         {
-            _channel.Close();
+            _channel.Dispose();
         }
 
         [TestMethod]

+ 8 - 4
src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Close_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_SendChannelCloseMessageSuccess.cs → src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_SendChannelCloseMessageSuccess.cs

@@ -6,11 +6,12 @@ using Moq;
 using Renci.SshNet.Channels;
 using Renci.SshNet.Common;
 using Renci.SshNet.Messages.Connection;
+using Renci.SshNet.Tests.Common;
 
 namespace Renci.SshNet.Tests.Classes.Channels
 {
     [TestClass]
-    public class ChannelSessionTest_Close_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_SendChannelCloseMessageSuccess
+    public class ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_SendChannelCloseMessageSuccess
     {
         private Mock<ISession> _sessionMock;
         private uint _localChannelNumber;
@@ -79,11 +80,14 @@ namespace Renci.SshNet.Tests.Classes.Channels
                                     _remoteChannelNumber)));
                         w.WaitOne();
                     });
-            _sessionMock.Setup(p => p.IsConnected).Returns(true);
+            _sessionMock.InSequence(_sequence).Setup(p => p.IsConnected).Returns(true);
             _sessionMock.InSequence(_sequence)
                 .Setup(
                     p => p.TrySendMessage(It.Is<ChannelCloseMessage>(c => c.LocalChannelNumber == _remoteChannelNumber)))
                 .Returns(true);
+            _sessionMock.InSequence(_sequence)
+                .Setup(s => s.WaitOnHandle(It.IsNotNull<EventWaitHandle>()))
+                .Callback<WaitHandle>(w => w.WaitOne());
 
             _channel = new ChannelSession(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize);
             _channel.Closed += (sender, args) => _channelClosedRegister.Add(args);
@@ -100,7 +104,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
 
         private void Act()
         {
-            _channel.Close();
+            _channel.Dispose();
         }
 
         [TestMethod]
@@ -112,7 +116,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
         [TestMethod]
         public void ExceptionShouldNeverHaveFired()
         {
-            Assert.AreEqual(0, _channelExceptionRegister.Count);
+            Assert.AreEqual(0, _channelExceptionRegister.Count, _channelExceptionRegister.AsString());
         }
 
         [TestMethod]

+ 2 - 2
src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Close_SessionIsConnectedAndChannelIsOpen_ChannelCloseReceived_SendChannelCloseMessageFailure.cs → src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseReceived_SendChannelCloseMessageFailure.cs

@@ -10,7 +10,7 @@ using Renci.SshNet.Messages.Connection;
 namespace Renci.SshNet.Tests.Classes.Channels
 {
     [TestClass]
-    public class ChannelSessionTest_Close_SessionIsConnectedAndChannelIsOpen_ChannelCloseReceived_SendChannelCloseMessageFailure
+    public class ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseReceived_SendChannelCloseMessageFailure
     {
         private Mock<ISession> _sessionMock;
         private uint _localChannelNumber;
@@ -97,7 +97,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
 
         private void Act()
         {
-            _channel.Close();
+            _channel.Dispose();
         }
 
         [TestMethod]

+ 8 - 4
src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Close_SessionIsConnectedAndChannelIsOpen_ChannelCloseReceived_SendChannelCloseMessageSuccess.cs → src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseReceived_SendChannelCloseMessageSuccess.cs

@@ -6,11 +6,12 @@ using Moq;
 using Renci.SshNet.Channels;
 using Renci.SshNet.Common;
 using Renci.SshNet.Messages.Connection;
+using Renci.SshNet.Tests.Common;
 
 namespace Renci.SshNet.Tests.Classes.Channels
 {
     [TestClass]
-    public class ChannelSessionTest_Close_SessionIsConnectedAndChannelIsOpen_ChannelCloseReceived_SendChannelCloseMessageSuccess
+    public class ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseReceived_SendChannelCloseMessageSuccess
     {
         private Mock<ISession> _sessionMock;
         private uint _localChannelNumber;
@@ -79,11 +80,14 @@ namespace Renci.SshNet.Tests.Classes.Channels
                                     _remoteChannelNumber)));
                         w.WaitOne();
                     });
-            _sessionMock.Setup(p => p.IsConnected).Returns(true);
+            _sessionMock.InSequence(_sequence).Setup(p => p.IsConnected).Returns(true);
             _sessionMock.InSequence(_sequence)
                 .Setup(
                     p => p.TrySendMessage(It.Is<ChannelCloseMessage>(c => c.LocalChannelNumber == _remoteChannelNumber)))
                 .Returns(true);
+            _sessionMock.InSequence(_sequence)
+                .Setup(s => s.WaitOnHandle(It.IsNotNull<EventWaitHandle>()))
+                .Callback<WaitHandle>(w => w.WaitOne());
 
             _channel = new ChannelSession(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize);
             _channel.Closed += (sender, args) => _channelClosedRegister.Add(args);
@@ -97,7 +101,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
 
         private void Act()
         {
-            _channel.Close();
+            _channel.Dispose();
         }
 
         [TestMethod]
@@ -109,7 +113,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
         [TestMethod]
         public void ExceptionShouldNeverHaveFired()
         {
-            Assert.AreEqual(0, _channelExceptionRegister.Count);
+            Assert.AreEqual(0, _channelExceptionRegister.Count, _channelExceptionRegister.AsString());
         }
 
         [TestMethod]

+ 2 - 2
src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Close_SessionIsConnectedAndChannelIsOpen_ChannelEofReceived_SendChannelCloseMessageFailure.cs → src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelEofReceived_SendChannelCloseMessageFailure.cs

@@ -10,7 +10,7 @@ using Renci.SshNet.Messages.Connection;
 namespace Renci.SshNet.Tests.Classes.Channels
 {
     [TestClass]
-    public class ChannelSessionTest_Close_SessionIsConnectedAndChannelIsOpen_ChannelEofReceived_SendChannelCloseMessageFailure
+    public class ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelEofReceived_SendChannelCloseMessageFailure
     {
         private Mock<ISession> _sessionMock;
         private uint _localChannelNumber;
@@ -97,7 +97,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
 
         private void Act()
         {
-            _channel.Close();
+            _channel.Dispose();
         }
 
         [TestMethod]

+ 2 - 2
src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Close_SessionIsConnectedAndChannelIsOpen_ChannelEofReceived_SendChannelCloseMessageSuccess.cs → src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelEofReceived_SendChannelCloseMessageSuccess.cs

@@ -10,7 +10,7 @@ using Renci.SshNet.Messages.Connection;
 namespace Renci.SshNet.Tests.Classes.Channels
 {
     [TestClass]
-    public class ChannelSessionTest_Close_SessionIsConnectedAndChannelIsOpen_ChannelEofReceived_SendChannelCloseMessageSuccess
+    public class ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelEofReceived_SendChannelCloseMessageSuccess
     {
         private Mock<ISession> _sessionMock;
         private uint _localChannelNumber;
@@ -107,7 +107,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
 
         private void Act()
         {
-            _channel.Close();
+            _channel.Dispose();
         }
 
         [TestMethod]

+ 2 - 2
src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Close_SessionIsConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived.cs → src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived.cs

@@ -10,7 +10,7 @@ using Renci.SshNet.Messages.Connection;
 namespace Renci.SshNet.Tests.Classes.Channels
 {
     [TestClass]
-    public class ChannelSessionTest_Close_SessionIsConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived
+    public class ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived
     {
         private Mock<ISession> _sessionMock;
         private Mock<IConnectionInfo> _connectionInfoMock;
@@ -105,7 +105,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
 
         private void Act()
         {
-            _channel.Close();
+            _channel.Dispose();
         }
 
         [TestMethod]

+ 2 - 2
src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Close_SessionIsConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived_SendChannelEofMessageFailure.cs → src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived_SendChannelEofMessageFailure.cs

@@ -10,7 +10,7 @@ using Renci.SshNet.Messages.Connection;
 namespace Renci.SshNet.Tests.Classes.Channels
 {
     [TestClass]
-    public class ChannelSessionTest_Close_SessionIsConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived_SendChannelEofMessageFailure
+    public class ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived_SendChannelEofMessageFailure
     {
         private Mock<ISession> _sessionMock;
         private Mock<IConnectionInfo> _connectionInfoMock;
@@ -105,7 +105,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
 
         private void Act()
         {
-            _channel.Close();
+            _channel.Dispose();
         }
 
         [TestMethod]

+ 2 - 2
src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Close_SessionIsNotConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived.cs → src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived.cs

@@ -10,7 +10,7 @@ using Renci.SshNet.Messages.Connection;
 namespace Renci.SshNet.Tests.Classes.Channels
 {
     [TestClass]
-    public class ChannelSessionTest_Close_SessionIsNotConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived
+    public class ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived
     {
         private Mock<ISession> _sessionMock;
         private uint _localChannelNumber;
@@ -96,7 +96,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
 
         private void Act()
         {
-            _channel.Close();
+            _channel.Dispose();
         }
 
         [TestMethod]

+ 2 - 2
src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Close_SessionIsNotConnectedAndChannelIsOpen_ChannelCloseReceived.cs → src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_ChannelCloseReceived.cs

@@ -10,7 +10,7 @@ using Renci.SshNet.Messages.Connection;
 namespace Renci.SshNet.Tests.Classes.Channels
 {
     [TestClass]
-    public class ChannelSessionTest_Close_SessionIsNotConnectedAndChannelIsOpen_ChannelCloseReceived
+    public class ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_ChannelCloseReceived
     {
         private Mock<ISession> _sessionMock;
         private uint _localChannelNumber;
@@ -93,7 +93,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
 
         private void Act()
         {
-            _channel.Close();
+            _channel.Dispose();
         }
 
         [TestMethod]

+ 2 - 2
src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Close_SessionIsNotConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived.cs → src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived.cs

@@ -10,7 +10,7 @@ using Renci.SshNet.Messages.Connection;
 namespace Renci.SshNet.Tests.Classes.Channels
 {
     [TestClass]
-    public class ChannelSessionTest_Close_SessionIsNotConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived
+    public class ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived
     {
         private Mock<ISession> _sessionMock;
         private uint _localChannelNumber;
@@ -89,7 +89,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
 
         private void Act()
         {
-            _channel.Close();
+            _channel.Dispose();
         }
 
         [TestMethod]

+ 1 - 1
src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Disposed_Closed.cs

@@ -3,7 +3,7 @@
 namespace Renci.SshNet.Tests.Classes.Channels
 {
     [TestClass]
-    public class ChannelSessionTest_Disposed_Closed : ChannelSessionTest_Close_Closed
+    public class ChannelSessionTest_Disposed_Closed : ChannelSessionTest_Dispose_Disposed
     {
         protected override void Act()
         {

+ 6 - 2
src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_OnSessionChannelCloseReceived_SessionIsConnectedAndChannelIsOpen.cs

@@ -6,6 +6,7 @@ using Moq;
 using Renci.SshNet.Channels;
 using Renci.SshNet.Common;
 using Renci.SshNet.Messages.Connection;
+using Renci.SshNet.Tests.Common;
 
 namespace Renci.SshNet.Tests.Classes.Channels
 {
@@ -79,11 +80,14 @@ namespace Renci.SshNet.Tests.Classes.Channels
                                     _remoteChannelNumber)));
                         w.WaitOne();
                     });
-            _sessionMock.Setup(p => p.IsConnected).Returns(true);
+            _sessionMock.InSequence(_sequence).Setup(p => p.IsConnected).Returns(true);
             _sessionMock.InSequence(_sequence)
                 .Setup(
                     p => p.TrySendMessage(It.Is<ChannelCloseMessage>(c => c.LocalChannelNumber == _remoteChannelNumber)))
                 .Returns(true);
+            _sessionMock.InSequence(_sequence)
+                .Setup(s => s.WaitOnHandle(It.IsNotNull<EventWaitHandle>()))
+                .Callback<WaitHandle>(w => w.WaitOne());
 
             _channel = new ChannelSession(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize);
             _channel.Closed += (sender, args) => _channelClosedRegister.Add(args);
@@ -107,7 +111,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
         [TestMethod]
         public void ExceptionShouldNeverHaveFired()
         {
-            Assert.AreEqual(0, _channelExceptionRegister.Count);
+            Assert.AreEqual(0, _channelExceptionRegister.Count, _channelExceptionRegister.AsString());
         }
 
         [TestMethod]

+ 2 - 2
src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Close_SessionIsConnectedAndChannelIsNotOpen.cs → src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsNotOpen.cs

@@ -9,7 +9,7 @@ using Renci.SshNet.Messages;
 namespace Renci.SshNet.Tests.Classes.Channels
 {
     [TestClass]
-    public class ChannelTest_Close_SessionIsConnectedAndChannelIsNotOpen
+    public class ChannelTest_Dispose_SessionIsConnectedAndChannelIsNotOpen
     {
         private Mock<ISession> _sessionMock;
         private uint _localWindowSize;
@@ -46,7 +46,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
 
         private void Act()
         {
-            _channel.Close();
+            _channel.Dispose();
         }
 
         [TestMethod]

+ 2 - 2
src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Close_SessionIsConnectedAndChannelIsOpen_EofNotReceived.cs → src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofNotReceived.cs

@@ -10,7 +10,7 @@ using Renci.SshNet.Messages.Connection;
 namespace Renci.SshNet.Tests.Classes.Channels
 {
     [TestClass]
-    public class ChannelTest_Close_SessionIsConnectedAndChannelIsOpen_EofNotReceived
+    public class ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofNotReceived
     {
         private Mock<ISession> _sessionMock;
         private uint _localChannelNumber;
@@ -84,7 +84,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
 
         private void Act()
         {
-            _channel.Close();
+            _channel.Dispose();
         }
 
         [TestMethod]

+ 2 - 2
src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Close_SessionIsConnectedAndChannelIsOpen_EofNotReceived_SendEofInvoked.cs → src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofNotReceived_SendEofInvoked.cs

@@ -10,7 +10,7 @@ using Renci.SshNet.Messages.Connection;
 namespace Renci.SshNet.Tests.Classes.Channels
 {
     [TestClass]
-    public class ChannelTest_Close_SessionIsConnectedAndChannelIsOpen_EofNotReceived_SendEofInvoked
+    public class ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofNotReceived_SendEofInvoked
     {
         private Mock<ISession> _sessionMock;
         private uint _localChannelNumber;
@@ -84,7 +84,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
 
         private void Act()
         {
-            _channel.Close();
+            _channel.Dispose();
         }
 
         [TestMethod]

+ 2 - 2
src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Close_SessionIsConnectedAndChannelIsOpen_EofReceived.cs → src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofReceived.cs

@@ -10,7 +10,7 @@ using Renci.SshNet.Messages.Connection;
 namespace Renci.SshNet.Tests.Classes.Channels
 {
     [TestClass]
-    public class ChannelTest_Close_SessionIsConnectedAndChannelIsOpen_EofReceived
+    public class ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofReceived
     {
         private Mock<ISession> _sessionMock;
         private uint _localChannelNumber;
@@ -93,7 +93,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
 
         private void Act()
         {
-            _channel.Close();
+            _channel.Dispose();
         }
 
         [TestMethod]

+ 2 - 2
src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Close_SessionIsNotConnectedAndChannelIsNotOpen.cs → src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsNotConnectedAndChannelIsNotOpen.cs

@@ -9,7 +9,7 @@ using Renci.SshNet.Messages;
 namespace Renci.SshNet.Tests.Classes.Channels
 {
     [TestClass]
-    public class ChannelTest_Close_SessionIsNotConnectedAndChannelIsNotOpen
+    public class ChannelTest_Dispose_SessionIsNotConnectedAndChannelIsNotOpen
     {
         private Mock<ISession> _sessionMock;
         private uint _localWindowSize;
@@ -46,7 +46,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
 
         private void Act()
         {
-            _channel.Close();
+            _channel.Dispose();
         }
 
         [TestMethod]

+ 2 - 2
src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Close_SessionIsNotConnectedAndChannelIsOpen.cs → src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsNotConnectedAndChannelIsOpen.cs

@@ -8,7 +8,7 @@ using Renci.SshNet.Messages;
 namespace Renci.SshNet.Tests.Classes.Channels
 {
     [TestClass]
-    public class ChannelTest_Close_SessionIsNotConnectedAndChannelIsOpen
+    public class ChannelTest_Dispose_SessionIsNotConnectedAndChannelIsOpen
     {
         private Mock<ISession> _sessionMock;
         private uint _localWindowSize;
@@ -46,7 +46,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
 
         private void Act()
         {
-            _channel.Close();
+            _channel.Dispose();
         }
 
         [TestMethod]

+ 2 - 2
src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelCloseReceived_OnClose_Exception.cs

@@ -28,9 +28,9 @@ namespace Renci.SshNet.Tests.Classes.Channels
         private void Arrange()
         {
             var random = new Random();
-            _localWindowSize = (uint)random.Next(1000, int.MaxValue);
+            _localWindowSize = (uint) random.Next(1000, int.MaxValue);
             _localPacketSize = _localWindowSize - 1;
-            _localChannelNumber = (uint)random.Next(0, int.MaxValue);
+            _localChannelNumber = (uint) random.Next(0, int.MaxValue);
             _onCloseException = new SystemException();
             _channelExceptionRegister = new List<ExceptionEventArgs>();
 

+ 11 - 5
src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelCloseReceived_SessionIsConnectedAndChannelIsOpen_EofNotReceived.cs

@@ -5,6 +5,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting;
 using Moq;
 using Renci.SshNet.Common;
 using Renci.SshNet.Messages.Connection;
+using Renci.SshNet.Tests.Common;
 
 namespace Renci.SshNet.Tests.Classes.Channels
 {
@@ -43,8 +44,13 @@ namespace Renci.SshNet.Tests.Classes.Channels
 
             _sessionMock = new Mock<ISession>(MockBehavior.Strict);
 
-            _sessionMock.Setup(p => p.IsConnected).Returns(true);
-            _sessionMock.Setup(p => p.TrySendMessage(It.Is<ChannelCloseMessage>(c => c.LocalChannelNumber == _remoteChannelNumber))).Returns(true);
+            var sequence = new MockSequence();
+
+            _sessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true);
+            _sessionMock.InSequence(sequence).Setup(p => p.TrySendMessage(It.Is<ChannelCloseMessage>(c => c.LocalChannelNumber == _remoteChannelNumber))).Returns(true);
+            _sessionMock.InSequence(sequence)
+                .Setup(s => s.WaitOnHandle(It.IsNotNull<EventWaitHandle>()))
+                .Callback<WaitHandle>(w => w.WaitOne());
 
             _channel = new ChannelStub(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize);
             _channel.Closed += (sender, args) => _channelClosedRegister.Add(args);
@@ -82,9 +88,9 @@ namespace Renci.SshNet.Tests.Classes.Channels
         }
 
         [TestMethod]
-        public void WaitOnHandleOnSessionShouldNeverBeInvoked()
+        public void WaitOnHandleOnSessionShouldBeInvokedOnce()
         {
-            _sessionMock.Verify(p => p.WaitOnHandle(It.IsAny<EventWaitHandle>()), Times.Never);
+            _sessionMock.Verify(p => p.WaitOnHandle(It.IsAny<EventWaitHandle>()), Times.Once);
         }
 
         [TestMethod]
@@ -97,7 +103,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
         [TestMethod]
         public void ExceptionShouldNeverHaveFired()
         {
-            Assert.AreEqual(0, _channelExceptionRegister.Count);
+            Assert.AreEqual(0, _channelExceptionRegister.Count, _channelExceptionRegister.AsString());
         }
     }
 }

+ 11 - 5
src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelCloseReceived_SessionIsConnectedAndChannelIsOpen_EofReceived.cs

@@ -5,6 +5,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting;
 using Moq;
 using Renci.SshNet.Common;
 using Renci.SshNet.Messages.Connection;
+using Renci.SshNet.Tests.Common;
 
 namespace Renci.SshNet.Tests.Classes.Channels
 {
@@ -43,10 +44,15 @@ namespace Renci.SshNet.Tests.Classes.Channels
 
             _sessionMock = new Mock<ISession>(MockBehavior.Strict);
 
-            _sessionMock.Setup(p => p.IsConnected).Returns(true);
-            _sessionMock.Setup(
+            var sequence = new MockSequence();
+
+            _sessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true);
+            _sessionMock.InSequence(sequence).Setup(
                 p => p.TrySendMessage(It.Is<ChannelCloseMessage>(c => c.LocalChannelNumber == _remoteChannelNumber)))
                 .Returns(true);
+            _sessionMock.InSequence(sequence)
+                .Setup(s => s.WaitOnHandle(It.IsNotNull<EventWaitHandle>()))
+                .Callback<WaitHandle>(w => w.WaitOne());
 
             _channel = new ChannelStub(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize);
             _channel.Closed += (sender, args) => _channelClosedRegister.Add(args);
@@ -87,9 +93,9 @@ namespace Renci.SshNet.Tests.Classes.Channels
         }
 
         [TestMethod]
-        public void WaitOnHandleOnSessionShouldNeverBeInvoked()
+        public void WaitOnHandleOnSessionShouldBeInvokedOnce()
         {
-            _sessionMock.Verify(p => p.WaitOnHandle(It.IsAny<EventWaitHandle>()), Times.Never);
+            _sessionMock.Verify(p => p.WaitOnHandle(It.IsAny<EventWaitHandle>()), Times.Once);
         }
 
         [TestMethod]
@@ -102,7 +108,7 @@ namespace Renci.SshNet.Tests.Classes.Channels
         [TestMethod]
         public void ExceptionShouldNeverHaveFired()
         {
-            Assert.AreEqual(0, _channelExceptionRegister.Count);
+            Assert.AreEqual(0, _channelExceptionRegister.Count, _channelExceptionRegister.AsString());
         }
     }
 }

+ 2 - 20
src/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Dispose_PortStarted_ChannelBound.cs

@@ -11,6 +11,7 @@ using Moq;
 using Renci.SshNet.Abstractions;
 using Renci.SshNet.Channels;
 using Renci.SshNet.Common;
+using Renci.SshNet.Tests.Common;
 
 namespace Renci.SshNet.Tests.Classes
 {
@@ -110,7 +111,6 @@ namespace Renci.SshNet.Tests.Classes
                     Thread.Sleep(_bindSleepTime);
                     _channelBindCompleted.Set();
                 });
-            _channelMock.Setup(p => p.Close());
             _channelMock.Setup(p => p.Dispose());
         }
 
@@ -190,7 +190,7 @@ namespace Renci.SshNet.Tests.Classes
         [TestMethod]
         public void ExceptionShouldNotHaveFired()
         {
-            Assert.AreEqual(0, _exceptionRegister.Count, GetReportedExceptions());
+            Assert.AreEqual(0, _exceptionRegister.Count, _exceptionRegister.AsString());
         }
 
         [TestMethod]
@@ -208,12 +208,6 @@ namespace Renci.SshNet.Tests.Classes
             _channelMock.Verify(p => p.Bind(), Times.Once);
         }
 
-        [TestMethod]
-        public void CloseOnChannelShouldBeInvokedOnce()
-        {
-            _channelMock.Verify(p => p.Close(), Times.Once);
-        }
-
         [TestMethod]
         public void DisposeOnChannelShouldBeInvokedOnce()
         {
@@ -248,17 +242,5 @@ namespace Renci.SshNet.Tests.Classes
             // wait until SOCKS client is bound to channel
             Assert.IsTrue(_channelBindStarted.WaitOne(TimeSpan.FromMilliseconds(200)));
         }
-
-        private string GetReportedExceptions()
-        {
-            if (_exceptionRegister.Count == 0)
-                return string.Empty;
-
-            string reportedExceptions = string.Empty;
-            foreach (var exceptionEvent in _exceptionRegister)
-                reportedExceptions += exceptionEvent.Exception.ToString();
-
-            return reportedExceptions;
-        }
     }
 }

+ 0 - 7
src/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Dispose_PortStarted_ChannelNotBound.cs

@@ -59,7 +59,6 @@ namespace Renci.SshNet.Tests.Classes
             _sessionMock.Setup(p => p.IsConnected).Returns(true);
             _sessionMock.Setup(p => p.ConnectionInfo).Returns(_connectionInfoMock.Object);
             _sessionMock.Setup(p => p.CreateChannelDirectTcpip()).Returns(_channelMock.Object);
-            _channelMock.Setup(p => p.Close());
             _channelMock.Setup(p => p.Dispose());
 
             _forwardedPort = new ForwardedPortDynamic(_endpoint.Address.ToString(), (uint) _endpoint.Port);
@@ -134,12 +133,6 @@ namespace Renci.SshNet.Tests.Classes
             Assert.AreEqual(0, _exceptionRegister.Count);
         }
 
-        [TestMethod]
-        public void CloseOnChannelShouldBeInvokedOnce()
-        {
-            _channelMock.Verify(p => p.Close(), Times.Once);
-        }
-
         [TestMethod]
         public void DisposeOnChannelShouldBeInvokedOnce()
         {

+ 4 - 10
src/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_SessionErrorOccurred_ChannelBound.cs

@@ -11,6 +11,7 @@ using Moq;
 using Renci.SshNet.Abstractions;
 using Renci.SshNet.Channels;
 using Renci.SshNet.Common;
+using Renci.SshNet.Tests.Common;
 
 namespace Renci.SshNet.Tests.Classes
 {
@@ -112,7 +113,6 @@ namespace Renci.SshNet.Tests.Classes
                     Thread.Sleep(_bindSleepTime);
                     _channelBindCompleted.Set();
                 });
-            _channelMock.Setup(p => p.Close());
             _channelMock.Setup(p => p.Dispose());
         }
 
@@ -195,9 +195,9 @@ namespace Renci.SshNet.Tests.Classes
         [TestMethod]
         public void ExceptionShouldHaveFiredOne()
         {
-            Assert.AreEqual(1, _exceptionRegister.Count);
-            Assert.IsNotNull(_exceptionRegister[0]);
-            Assert.AreSame(_sessionException, _exceptionRegister[0].Exception);
+            Assert.AreEqual(1, _exceptionRegister.Count, _exceptionRegister.AsString());
+            Assert.IsNotNull(_exceptionRegister[0], _exceptionRegister.AsString());
+            Assert.AreSame(_sessionException, _exceptionRegister[0].Exception, _exceptionRegister.AsString());
         }
 
         [TestMethod]
@@ -215,12 +215,6 @@ namespace Renci.SshNet.Tests.Classes
             _channelMock.Verify(p => p.Bind(), Times.Once);
         }
 
-        [TestMethod]
-        public void CloseOnChannelShouldBeInvokedOnce()
-        {
-            _channelMock.Verify(p => p.Close(), Times.Once);
-        }
-
         [TestMethod]
         public void DisposeOnChannelShouldBeInvokedOnce()
         {

+ 2 - 22
src/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Started_SocketSendShutdownImmediately.cs

@@ -8,6 +8,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting;
 using Moq;
 using Renci.SshNet.Channels;
 using Renci.SshNet.Common;
+using Renci.SshNet.Tests.Common;
 
 namespace Renci.SshNet.Tests.Classes
 {
@@ -90,7 +91,6 @@ namespace Renci.SshNet.Tests.Classes
             _sessionMock.InSequence(seq).Setup(p => p.CreateChannelDirectTcpip()).Returns(_channelMock.Object);
             _sessionMock.InSequence(seq).Setup(p => p.ConnectionInfo).Returns(_connectionInfoMock.Object);
             _connectionInfoMock.InSequence(seq).Setup(p => p.Timeout).Returns(_connectionTimeout);
-            _channelMock.InSequence(seq).Setup(p => p.Close());
             _channelMock.InSequence(seq).Setup(p => p.Dispose()).Callback(() => _channelDisposed.Set());
         }
 
@@ -138,7 +138,7 @@ namespace Renci.SshNet.Tests.Classes
         [TestMethod]
         public void ExceptionShouldNeverBeFired()
         {
-            Assert.AreEqual(0, _exceptionRegister.Count, GetExceptions());
+            Assert.AreEqual(0, _exceptionRegister.Count, _exceptionRegister.AsString());
         }
 
         [TestMethod]
@@ -147,30 +147,10 @@ namespace Renci.SshNet.Tests.Classes
             _sessionMock.Verify(p => p.CreateChannelDirectTcpip(), Times.Once);
         }
 
-        [TestMethod]
-        public void CloseOnChannelShouldBeInvokedOnce()
-        {
-            _channelMock.Verify(p => p.Close(), Times.Once);
-        }
-
         [TestMethod]
         public void DisposeOnChannelShouldBeInvokedOnce()
         {
             _channelMock.Verify(p => p.Dispose(), Times.Once);
         }
-
-        private string GetExceptions()
-        {
-            var sb = new StringBuilder();
-
-            foreach (var exceptionEventArgs in _exceptionRegister)
-            {
-                if (sb.Length > 0)
-                    sb.AppendLine();
-                sb.Append(exceptionEventArgs.Exception);
-            }
-
-            return sb.ToString();
-        }
     }
 }

+ 2 - 22
src/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Started_SocketVersionNotSupported.cs

@@ -8,6 +8,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting;
 using Moq;
 using Renci.SshNet.Channels;
 using Renci.SshNet.Common;
+using Renci.SshNet.Tests.Common;
 
 namespace Renci.SshNet.Tests.Classes
 {
@@ -77,7 +78,6 @@ namespace Renci.SshNet.Tests.Classes
             _sessionMock.InSequence(seq).Setup(p => p.CreateChannelDirectTcpip()).Returns(_channelMock.Object);
             _sessionMock.InSequence(seq).Setup(p => p.ConnectionInfo).Returns(_connectionInfoMock.Object);
             _connectionInfoMock.InSequence(seq).Setup(p => p.Timeout).Returns(_connectionTimeout);
-            _channelMock.InSequence(seq).Setup(p => p.Close());
             _channelMock.InSequence(seq).Setup(p => p.Dispose());
         }
 
@@ -138,7 +138,7 @@ namespace Renci.SshNet.Tests.Classes
         [TestMethod]
         public void ExceptionShouldHaveFiredOnce()
         {
-            Assert.AreEqual(1, _exceptionRegister.Count, GetExceptions());
+            Assert.AreEqual(1, _exceptionRegister.Count, _exceptionRegister.AsString());
 
             var exception = _exceptionRegister[0].Exception;
             Assert.IsNotNull(exception);
@@ -153,30 +153,10 @@ namespace Renci.SshNet.Tests.Classes
             _sessionMock.Verify(p => p.CreateChannelDirectTcpip(), Times.Once);
         }
 
-        [TestMethod]
-        public void CloseOnChannelShouldBeInvokedOnce()
-        {
-            _channelMock.Verify(p => p.Close(), Times.Once);
-        }
-
         [TestMethod]
         public void DisposeOnChannelShouldBeInvokedOnce()
         {
             _channelMock.Verify(p => p.Dispose(), Times.Once);
         }
-
-        private string GetExceptions()
-        {
-            var sb = new StringBuilder();
-
-            foreach (var exceptionEventArgs in _exceptionRegister)
-            {
-                if (sb.Length > 0)
-                    sb.AppendLine();
-                sb.Append(exceptionEventArgs.Exception);
-            }
-
-            return sb.ToString();
-        }
     }
 }

+ 0 - 7
src/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Stop_PortStarted_ChannelBound.cs

@@ -110,7 +110,6 @@ namespace Renci.SshNet.Tests.Classes
                     Thread.Sleep(_bindSleepTime);
                     _channelBindCompleted.Set();
                 });
-            _channelMock.Setup(p => p.Close());
             _channelMock.Setup(p => p.Dispose());
         }
 
@@ -196,12 +195,6 @@ namespace Renci.SshNet.Tests.Classes
             Assert.AreEqual(0, _exceptionRegister.Count);
         }
 
-        [TestMethod]
-        public void CloseOnChannelShouldBeInvokedOnce()
-        {
-            _channelMock.Verify(p => p.Close(), Times.Once);
-        }
-
         [TestMethod]
         public void DisposeOnChannelShouldBeInvokedOnce()
         {

+ 0 - 7
src/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Stop_PortStarted_ChannelNotBound.cs

@@ -59,7 +59,6 @@ namespace Renci.SshNet.Tests.Classes
             _sessionMock.Setup(p => p.IsConnected).Returns(true);
             _sessionMock.Setup(p => p.ConnectionInfo).Returns(_connectionInfoMock.Object);
             _sessionMock.Setup(p => p.CreateChannelDirectTcpip()).Returns(_channelMock.Object);
-            _channelMock.Setup(p => p.Close());
             _channelMock.Setup(p => p.Dispose());
 
             _forwardedPort = new ForwardedPortDynamic(_endpoint.Address.ToString(), (uint) _endpoint.Port);
@@ -134,12 +133,6 @@ namespace Renci.SshNet.Tests.Classes
             Assert.AreEqual(0, _exceptionRegister.Count);
         }
 
-        [TestMethod]
-        public void CloseOnChannelShouldBeInvokedOnce()
-        {
-            _channelMock.Verify(p => p.Close(), Times.Once);
-        }
-
         [TestMethod]
         public void DisposeOnChannelShouldBeInvokedOnce()
         {

+ 0 - 7
src/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Dispose_PortStarted_ChannelBound.cs

@@ -85,7 +85,6 @@ namespace Renci.SshNet.Tests.Classes
                     Thread.Sleep(_bindSleepTime);
                     _channelBindCompleted.Set();
                 });
-            _channelMock.Setup(p => p.Close());
             _channelMock.Setup(p => p.Dispose());
 
             _forwardedPort.Closing += (sender, args) => _closingRegister.Add(args);
@@ -186,12 +185,6 @@ namespace Renci.SshNet.Tests.Classes
             _channelMock.Verify(p => p.Bind(), Times.Once);
         }
 
-        [TestMethod]
-        public void CloseOnChannelShouldBeInvokedOnce()
-        {
-            _channelMock.Verify(p => p.Close(), Times.Once);
-        }
-
         [TestMethod]
         public void DisposeOnChannelShouldBeInvokedOnce()
         {

+ 0 - 1
src/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Start_PortNeverStarted.cs

@@ -85,7 +85,6 @@ namespace Renci.SshNet.Tests.Classes
                     if (handlerSocket != null && handlerSocket.Connected)
                         handlerSocket.Shutdown(SocketShutdown.Both);
                 });
-            _channelMock.Setup(p => p.Close());
             _channelMock.Setup(p => p.Dispose());
 
             using (var client = new Socket(_localEndpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp))

+ 4 - 5
src/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Start_PortStarted.cs

@@ -98,11 +98,10 @@ namespace Renci.SshNet.Tests.Classes
             _sessionMock.Setup(p => p.CreateChannelDirectTcpip()).Returns(_channelMock.Object);
             _channelMock.Setup(p => p.Open(_forwardedPort.Host, _forwardedPort.Port, _forwardedPort, It.IsAny<Socket>())).Callback<string, uint, IForwardedPort, Socket>((address, port, forwardedPort, socket) => handlerSocket = socket);
             _channelMock.Setup(p => p.Bind()).Callback(() =>
-            {
-                if (handlerSocket != null && handlerSocket.Connected)
-                    handlerSocket.Shutdown(SocketShutdown.Both);
-            });
-            _channelMock.Setup(p => p.Close());
+                {
+                    if (handlerSocket != null && handlerSocket.Connected)
+                        handlerSocket.Shutdown(SocketShutdown.Both);
+                });
             _channelMock.Setup(p => p.Dispose());
 
             using (var client = new Socket(_localEndpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp))

+ 0 - 1
src/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Start_PortStopped.cs

@@ -89,7 +89,6 @@ namespace Renci.SshNet.Tests.Classes
                 if (handlerSocket != null && handlerSocket.Connected)
                     handlerSocket.Shutdown(SocketShutdown.Both);
             });
-            _channelMock.Setup(p => p.Close());
             _channelMock.Setup(p => p.Dispose());
 
             using (var client = new Socket(_localEndpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp))

+ 0 - 7
src/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Stop_PortStarted_ChannelBound.cs

@@ -103,7 +103,6 @@ namespace Renci.SshNet.Tests.Classes
                     Thread.Sleep(_bindSleepTime);
                     _channelBindCompleted.Set();
                 });
-            _channelMock.Setup(p => p.Close());
             _channelMock.Setup(p => p.Dispose());
         }
 
@@ -201,12 +200,6 @@ namespace Renci.SshNet.Tests.Classes
             _channelMock.Verify(p => p.Bind(), Times.Once);
         }
 
-        [TestMethod]
-        public void CloseOnChannelShouldBeInvokedOnce()
-        {
-            _channelMock.Verify(p => p.Close(), Times.Once);
-        }
-
         [TestMethod]
         public void DisposeOnChannelShouldBeInvokedOnce()
         {

+ 0 - 7
src/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Dispose_PortStarted_ChannelBound.cs

@@ -134,7 +134,6 @@ namespace Renci.SshNet.Tests.Classes
                                 Thread.Sleep(_bindSleepTime);
                                 _channelBindCompleted.Set();
                             });
-            _channelMock.Setup(p => p.Close());
             _channelMock.Setup(p => p.Dispose());
             _sessionMock.Setup(
                 p =>
@@ -239,12 +238,6 @@ namespace Renci.SshNet.Tests.Classes
                         ForwardedPort), Times.Once);
         }
 
-        [TestMethod]
-        public void CloseOnChannelShouldBeInvokedOnce()
-        {
-            _channelMock.Verify(p => p.Close(), Times.Once);
-        }
-
         [TestMethod]
         public void DisposeOnChannelShouldBeInvokedOnce()
         {

+ 0 - 2
src/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Start_PortNeverStarted.cs

@@ -114,7 +114,6 @@ namespace Renci.SshNet.Tests.Classes
                         It.Is<IPEndPoint>(
                             ep => ep.Address.Equals(_remoteEndpoint.Address) && ep.Port == _remoteEndpoint.Port),
                         _forwardedPort));
-            channelMock.Setup(p => p.Close());
             channelMock.Setup(p => p.Dispose());
 
             _sessionMock.Raise(p => p.ChannelOpenReceived += null,
@@ -125,7 +124,6 @@ namespace Renci.SshNet.Tests.Classes
 
             _sessionMock.Verify(p => p.CreateChannelForwardedTcpip(channelNumber, initialWindowSize, maximumPacketSize), Times.Once);
             channelMock.Verify(p => p.Bind(It.Is<IPEndPoint>(ep => ep.Address.Equals(_remoteEndpoint.Address) && ep.Port == _remoteEndpoint.Port), _forwardedPort), Times.Once);
-            channelMock.Verify(p => p.Close(), Times.Once);
             channelMock.Verify(p => p.Dispose(), Times.Once);
         }
 

+ 0 - 2
src/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Start_PortStarted.cs

@@ -131,7 +131,6 @@ namespace Renci.SshNet.Tests.Classes
                         It.Is<IPEndPoint>(
                             ep => ep.Address.Equals(_remoteEndpoint.Address) && ep.Port == _remoteEndpoint.Port),
                         _forwardedPort));
-            channelMock.Setup(p => p.Close());
             channelMock.Setup(p => p.Dispose());
 
             _sessionMock.Raise(p => p.ChannelOpenReceived += null,
@@ -142,7 +141,6 @@ namespace Renci.SshNet.Tests.Classes
 
             _sessionMock.Verify(p => p.CreateChannelForwardedTcpip(channelNumber, initialWindowSize, maximumPacketSize), Times.Once);
             channelMock.Verify(p => p.Bind(It.Is<IPEndPoint>(ep => ep.Address.Equals(_remoteEndpoint.Address) && ep.Port == _remoteEndpoint.Port), _forwardedPort), Times.Once);
-            channelMock.Verify(p => p.Close(), Times.Once);
             channelMock.Verify(p => p.Dispose(), Times.Once);
         }
 

+ 3 - 5
src/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Start_PortStopped.cs

@@ -120,7 +120,7 @@ namespace Renci.SshNet.Tests.Classes
             var originatorAddress = new Random().Next().ToString(CultureInfo.InvariantCulture);
             var originatorPort = (uint)new Random().Next(0, int.MaxValue);
             var channelMock = new Mock<IChannelForwardedTcpip>(MockBehavior.Strict);
-            var channelDiposed = new ManualResetEvent(false);
+            var channelDisposed = new ManualResetEvent(false);
 
             _sessionMock.Setup(
                 p =>
@@ -131,8 +131,7 @@ namespace Renci.SshNet.Tests.Classes
                         It.Is<IPEndPoint>(
                             ep => ep.Address.Equals(_remoteEndpoint.Address) && ep.Port == _remoteEndpoint.Port),
                         _forwardedPort));
-            channelMock.Setup(p => p.Close());
-            channelMock.Setup(p => p.Dispose()).Callback(() => channelDiposed.Set());
+            channelMock.Setup(p => p.Dispose()).Callback(() => channelDisposed.Set());
 
             _sessionMock.Raise(p => p.ChannelOpenReceived += null,
                 new MessageEventArgs<ChannelOpenMessage>(new ChannelOpenMessage(channelNumber, initialWindowSize,
@@ -141,11 +140,10 @@ namespace Renci.SshNet.Tests.Classes
                         originatorPort))));
 
             // wait for channel to be disposed
-            channelDiposed.WaitOne(TimeSpan.FromMilliseconds(200));
+            channelDisposed.WaitOne(TimeSpan.FromMilliseconds(200));
 
             _sessionMock.Verify(p => p.CreateChannelForwardedTcpip(channelNumber, initialWindowSize, maximumPacketSize), Times.Once);
             channelMock.Verify(p => p.Bind(It.Is<IPEndPoint>(ep => ep.Address.Equals(_remoteEndpoint.Address) && ep.Port == _remoteEndpoint.Port), _forwardedPort), Times.Once);
-            channelMock.Verify(p => p.Close(), Times.Once);
             channelMock.Verify(p => p.Dispose(), Times.Once);
         }
 

+ 0 - 2
src/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Started.cs

@@ -107,7 +107,6 @@ namespace Renci.SshNet.Tests.Classes
                         It.Is<IPEndPoint>(
                             ep => ep.Address.Equals(_remoteEndpoint.Address) && ep.Port == _remoteEndpoint.Port),
                         _forwardedPort));
-            channelMock.Setup(p => p.Close());
             channelMock.Setup(p => p.Dispose()).Callback(() => channelDisposed.Set());
 
             _sessionMock.Raise(p => p.ChannelOpenReceived += null,
@@ -121,7 +120,6 @@ namespace Renci.SshNet.Tests.Classes
 
             _sessionMock.Verify(p => p.CreateChannelForwardedTcpip(channelNumber, initialWindowSize, maximumPacketSize), Times.Once);
             channelMock.Verify(p => p.Bind(It.Is<IPEndPoint>(ep => ep.Address.Equals(_remoteEndpoint.Address) && ep.Port == _remoteEndpoint.Port), _forwardedPort), Times.Once);
-            channelMock.Verify(p => p.Close(), Times.Once);
             channelMock.Verify(p => p.Dispose(), Times.Once);
 
             Assert.AreEqual(0, _closingRegister.Count);

+ 0 - 6
src/Renci.SshNet.Tests/Classes/ScpClientTest_Upload_FileInfoAndPath_SendExecRequestReturnsFalse.cs

@@ -101,12 +101,6 @@ namespace Renci.SshNet.Tests.Classes
             _channelSessionMock.Verify(p => p.SendExecRequest(string.Format("scp -t \"{0}\"", _path)), Times.Once);
         }
 
-        [TestMethod]
-        public void CloseOnChannelShouldNeverBeInvoked()
-        {
-            _channelSessionMock.Verify(p => p.Close(), Times.Never);
-        }
-
         [TestMethod]
         public void DisposeOnChannelShouldBeInvokedOnce()
         {

+ 0 - 7
src/Renci.SshNet.Tests/Classes/ScpClientTest_Upload_FileInfoAndPath_Success.cs

@@ -101,7 +101,6 @@ namespace Renci.SshNet.Tests.Classes
                 .Setup(
                     p => p.SendData(It.Is<byte[]>(b => b.SequenceEqual(new byte[] {0}))));
             _pipeStreamMock.InSequence(sequence).Setup(p => p.ReadByte()).Returns(0);
-            _channelSessionMock.InSequence(sequence).Setup(p => p.Close());
             _channelSessionMock.InSequence(sequence).Setup(p => p.Dispose());
             _pipeStreamMock.As<IDisposable>().InSequence(sequence).Setup(p => p.Dispose());
         }
@@ -131,12 +130,6 @@ namespace Renci.SshNet.Tests.Classes
             _channelSessionMock.Verify(p => p.SendExecRequest(string.Format("scp -t \"{0}\"", _path)), Times.Once);
         }
 
-        [TestMethod]
-        public void CloseOnChannelShouldBeInvokedOnce()
-        {
-            _channelSessionMock.Verify(p => p.Close(), Times.Once);
-        }
-
         [TestMethod]
         public void DisposeOnChannelShouldBeInvokedOnce()
         {

+ 2 - 1
src/Renci.SshNet.Tests/Classes/SessionTest_Connected_ConnectionReset.cs

@@ -4,6 +4,7 @@ using System.Threading;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using Renci.SshNet.Common;
 using Renci.SshNet.Messages.Transport;
+using Renci.SshNet.Tests.Common;
 
 namespace Renci.SshNet.Tests.Classes
 {
@@ -51,7 +52,7 @@ namespace Renci.SshNet.Tests.Classes
         [TestMethod]
         public void ErrorOccurredIsRaisedOnce()
         {
-            Assert.AreEqual(1, ErrorOccurredRegister.Count);
+            Assert.AreEqual(1, ErrorOccurredRegister.Count, ErrorOccurredRegister.AsString());
 
             var errorOccurred = ErrorOccurredRegister[0];
             Assert.IsNotNull(errorOccurred);

+ 2 - 1
src/Renci.SshNet.Tests/Classes/SessionTest_Connected_ServerSendsBadPacket.cs

@@ -4,6 +4,7 @@ using System.Threading;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using Renci.SshNet.Common;
 using Renci.SshNet.Messages.Transport;
+using Renci.SshNet.Tests.Common;
 
 namespace Renci.SshNet.Tests.Classes
 {
@@ -52,7 +53,7 @@ namespace Renci.SshNet.Tests.Classes
         [TestMethod]
         public void ErrorOccurredIsRaisedOnce()
         {
-            Assert.AreEqual(1, ErrorOccurredRegister.Count);
+            Assert.AreEqual(1, ErrorOccurredRegister.Count, ErrorOccurredRegister.AsString());
 
             var errorOccurred = ErrorOccurredRegister[0];
             Assert.IsNotNull(errorOccurred);

+ 2 - 1
src/Renci.SshNet.Tests/Classes/SessionTest_Connected_ServerShutsDownSendAfterSendingIncompletePacket.cs

@@ -5,6 +5,7 @@ using System.Threading;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using Renci.SshNet.Common;
 using Renci.SshNet.Messages.Transport;
+using Renci.SshNet.Tests.Common;
 
 namespace Renci.SshNet.Tests.Classes
 {
@@ -58,7 +59,7 @@ namespace Renci.SshNet.Tests.Classes
         [TestMethod]
         public void ErrorOccurredIsRaisedOnce()
         {
-            Assert.AreEqual(1, ErrorOccurredRegister.Count);
+            Assert.AreEqual(1, ErrorOccurredRegister.Count, ErrorOccurredRegister.AsString());
 
             var errorOccurred = ErrorOccurredRegister[0];
             Assert.IsNotNull(errorOccurred);

+ 2 - 1
src/Renci.SshNet.Tests/Classes/SessionTest_Connected_ServerShutsDownSocket.cs

@@ -4,6 +4,7 @@ using System.Threading;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using Renci.SshNet.Common;
 using Renci.SshNet.Messages.Transport;
+using Renci.SshNet.Tests.Common;
 
 namespace Renci.SshNet.Tests.Classes
 {
@@ -51,7 +52,7 @@ namespace Renci.SshNet.Tests.Classes
         [TestMethod]
         public void ErrorOccurredIsRaisedOnce()
         {
-            Assert.AreEqual(1, ErrorOccurredRegister.Count);
+            Assert.AreEqual(1, ErrorOccurredRegister.Count, ErrorOccurredRegister.AsString());
 
             var errorOccurred = ErrorOccurredRegister[0];
             Assert.IsNotNull(errorOccurred);

+ 1 - 1
src/Renci.SshNet.Tests/Classes/SshClientTest.cs

@@ -109,7 +109,7 @@ namespace Renci.SshNet.Tests.Classes
             {
                 client.ErrorOccurred += delegate(object sender, ExceptionEventArgs e)
                 {
-                    Console.WriteLine("Error occured: " + e.Exception.ToString());
+                    Console.WriteLine("Error occured: " + e.Exception);
                     exceptionOccured = true;
                 };
 

+ 0 - 2
src/Renci.SshNet.Tests/Classes/SshCommandTest_BeginExecute_EndExecuteInvokedOnAsyncResultFromPreviousInvocation.cs

@@ -47,8 +47,6 @@ namespace Renci.SshNet.Tests.Classes
             _channelSessionAMock.InSequence(seq).Setup(p => p.SendExecRequest(_commandText))
                 .Returns(true)
                 .Raises(c => c.Closed += null, new ChannelEventArgs(5));
-            _channelSessionAMock.InSequence(seq).Setup(p => p.IsOpen).Returns(true);
-            _channelSessionAMock.InSequence(seq).Setup(p => p.Close());
             _channelSessionAMock.InSequence(seq).Setup(p => p.Dispose());
 
             _sshCommand = new SshCommand(_sessionMock.Object, _commandText, _encoding);

+ 1 - 4
src/Renci.SshNet.Tests/Classes/SshCommandTest_EndExecute.cs

@@ -40,7 +40,6 @@ namespace Renci.SshNet.Tests.Classes
             _channelSessionMock.InSequence(seq).Setup(p => p.SendExecRequest(_commandText))
                 .Returns(true)
                 .Raises(c => c.Closed += null, new ChannelEventArgs(5));
-            _channelSessionMock.InSequence(seq).Setup(p => p.IsOpen).Returns(false);
             _channelSessionMock.InSequence(seq).Setup(p => p.Dispose());
 
             var asyncResult = _sshCommand.BeginExecute();
@@ -59,14 +58,12 @@ namespace Renci.SshNet.Tests.Classes
             _channelSessionMock.InSequence(seq).Setup(p => p.SendExecRequest(_commandText))
                 .Returns(true)
                 .Raises(c => c.Closed += null, new ChannelEventArgs(5));
-            _channelSessionMock.InSequence(seq).Setup(p => p.IsOpen).Returns(true);
-            _channelSessionMock.InSequence(seq).Setup(p => p.Close());
             _channelSessionMock.InSequence(seq).Setup(p => p.Dispose());
 
             var asyncResult = _sshCommand.BeginExecute();
             _sshCommand.EndExecute(asyncResult);
 
-            _channelSessionMock.Verify(p => p.Close(), Times.Once);
+            _channelSessionMock.Verify(p => p.Dispose(), Times.Once);
         }
     }
 }

+ 0 - 8
src/Renci.SshNet.Tests/Classes/SshCommandTest_EndExecute_ChannelOpen.cs

@@ -55,8 +55,6 @@ namespace Renci.SshNet.Tests.Classes
             _channelSessionMock.InSequence(seq).Setup(p => p.SendExecRequest(_commandText))
                 .Returns(true)
                 .Raises(c => c.Closed += null, new ChannelEventArgs(5));
-            _channelSessionMock.InSequence(seq).Setup(p => p.IsOpen).Returns(true);
-            _channelSessionMock.InSequence(seq).Setup(p => p.Close());
             _channelSessionMock.InSequence(seq).Setup(p => p.Dispose());
 
             _sshCommand = new SshCommand(_sessionMock.Object, _commandText, _encoding);
@@ -79,12 +77,6 @@ namespace Renci.SshNet.Tests.Classes
             _actual = _sshCommand.EndExecute(_asyncResult);
         }
 
-        [TestMethod]
-        public void ChannelSessionShouldBeClosedOnce()
-        {
-            _channelSessionMock.Verify(p => p.Close(), Times.Once);
-        }
-
         [TestMethod]
         public void ChannelSessionShouldBeDisposedOnce()
         {

+ 0 - 6
src/Renci.SshNet.Tests/Classes/SubsystemSession_Connect_Connected.cs

@@ -112,12 +112,6 @@ namespace Renci.SshNet.Tests.Classes
             _channelMock.Verify(p => p.IsOpen, Times.Exactly(2));
         }
 
-        [TestMethod]
-        public void CloseOnChannelShouldNeverBeInvoked()
-        {
-            _channelMock.Verify(p => p.Close(), Times.Never);
-        }
-
         [TestMethod]
         public void DisposeOnChannelShouldNeverBeInvoked()
         {

+ 1 - 14
src/Renci.SshNet.Tests/Classes/SubsystemSession_Connect_Disconnected.cs

@@ -47,7 +47,6 @@ namespace Renci.SshNet.Tests.Classes
             _sessionMock.InSequence(_sequence).Setup(p => p.CreateChannelSession()).Returns(_channelBeforeDisconnectMock.Object);
             _channelBeforeDisconnectMock.InSequence(_sequence).Setup(p => p.Open());
             _channelBeforeDisconnectMock.InSequence(_sequence).Setup(p => p.SendSubsystemRequest(_subsystemName)).Returns(true);
-            _channelBeforeDisconnectMock.InSequence(_sequence).Setup(p => p.Close());
             _channelBeforeDisconnectMock.InSequence(_sequence).Setup(p => p.Dispose());
             _sessionMock.InSequence(_sequence).Setup(p => p.CreateChannelSession()).Returns(_channelAfterDisconnectMock.Object);
             _channelAfterDisconnectMock.InSequence(_sequence).Setup(p => p.Open());
@@ -101,18 +100,6 @@ namespace Renci.SshNet.Tests.Classes
             _channelAfterDisconnectMock.Verify(p => p.IsOpen, Times.Once);
         }
 
-        [TestMethod]
-        public void CloseOnChannelBeforeDisconnectShouldBeInvokedOnce()
-        {
-            _channelBeforeDisconnectMock.Verify(p => p.Close(), Times.Once);
-        }
-
-        [TestMethod]
-        public void CloseOnChannelAfterDisconnectShouldNeverBeInvoked()
-        {
-            _channelAfterDisconnectMock.Verify(p => p.Close(), Times.Never);
-        }
-
         [TestMethod]
         public void DisposeOnChannelBeforeDisconnectShouldBeInvokedOnce()
         {
@@ -120,7 +107,7 @@ namespace Renci.SshNet.Tests.Classes
         }
 
         [TestMethod]
-        public void DisposeOnChannelAfterDisconnectShouldBeInvokedOnce()
+        public void DisposeOnChannelAfterDisconnectShouldNeverBeInvoked()
         {
             _channelAfterDisconnectMock.Verify(p => p.Dispose(), Times.Never);
         }

+ 0 - 7
src/Renci.SshNet.Tests/Classes/SubsystemSession_Disconnect_Connected.cs

@@ -45,7 +45,6 @@ namespace Renci.SshNet.Tests.Classes
             _sessionMock.InSequence(_sequence).Setup(p => p.CreateChannelSession()).Returns(_channelMock.Object);
             _channelMock.InSequence(_sequence).Setup(p => p.Open());
             _channelMock.InSequence(_sequence).Setup(p => p.SendSubsystemRequest(_subsystemName)).Returns(true);
-            _channelMock.InSequence(_sequence).Setup(p => p.Close());
             _channelMock.InSequence(_sequence).Setup(p => p.Dispose());
 
             _subsystemSession = new SubsystemSessionStub(
@@ -81,12 +80,6 @@ namespace Renci.SshNet.Tests.Classes
             Assert.IsFalse(_subsystemSession.IsOpen);
         }
 
-        [TestMethod]
-        public void CloseOnChannelShouldBeInvokedOnce()
-        {
-            _channelMock.Verify(p => p.Close(), Times.Once);
-        }
-
         [TestMethod]
         public void DisposeOnChannelShouldBeInvokedOnce()
         {

+ 0 - 7
src/Renci.SshNet.Tests/Classes/SubsystemSession_Disconnect_Disposed.cs

@@ -44,7 +44,6 @@ namespace Renci.SshNet.Tests.Classes
             _sessionMock.InSequence(sequence).Setup(p => p.CreateChannelSession()).Returns(_channelMock.Object);
             _channelMock.InSequence(sequence).Setup(p => p.Open());
             _channelMock.InSequence(sequence).Setup(p => p.SendSubsystemRequest(_subsystemName)).Returns(true);
-            _channelMock.InSequence(sequence).Setup(p => p.Close());
             _channelMock.InSequence(sequence).Setup(p => p.Dispose());
 
             _subsystemSession = new SubsystemSessionStub(
@@ -81,12 +80,6 @@ namespace Renci.SshNet.Tests.Classes
             Assert.IsFalse(_subsystemSession.IsOpen);
         }
 
-        [TestMethod]
-        public void CloseOnChannelShouldBeInvokedOnce()
-        {
-            _channelMock.Verify(p => p.Close(), Times.Once);
-        }
-
         [TestMethod]
         public void DisposeOnChannelShouldBeInvokedOnce()
         {

+ 0 - 7
src/Renci.SshNet.Tests/Classes/SubsystemSession_Dispose_Connected.cs

@@ -44,7 +44,6 @@ namespace Renci.SshNet.Tests.Classes
             _sessionMock.InSequence(sequence).Setup(p => p.CreateChannelSession()).Returns(_channelMock.Object);
             _channelMock.InSequence(sequence).Setup(p => p.Open());
             _channelMock.InSequence(sequence).Setup(p => p.SendSubsystemRequest(_subsystemName)).Returns(true);
-            _channelMock.InSequence(sequence).Setup(p => p.Close());
             _channelMock.InSequence(sequence).Setup(p => p.Dispose());
 
             _subsystemSession = new SubsystemSessionStub(
@@ -80,12 +79,6 @@ namespace Renci.SshNet.Tests.Classes
             Assert.IsFalse(_subsystemSession.IsOpen);
         }
 
-        [TestMethod]
-        public void CloseOnChannelShouldBeInvokedOnce()
-        {
-            _channelMock.Verify(p => p.Close(), Times.Once);
-        }
-
         [TestMethod]
         public void DisposeOnChannelShouldBeInvokedOnce()
         {

+ 0 - 7
src/Renci.SshNet.Tests/Classes/SubsystemSession_Dispose_Disconnected.cs

@@ -44,7 +44,6 @@ namespace Renci.SshNet.Tests.Classes
             _sessionMock.InSequence(sequence).Setup(p => p.CreateChannelSession()).Returns(_channelMock.Object);
             _channelMock.InSequence(sequence).Setup(p => p.Open());
             _channelMock.InSequence(sequence).Setup(p => p.SendSubsystemRequest(_subsystemName)).Returns(true);
-            _channelMock.InSequence(sequence).Setup(p => p.Close());
             _channelMock.InSequence(sequence).Setup(p => p.Dispose());
 
             _subsystemSession = new SubsystemSessionStub(
@@ -81,12 +80,6 @@ namespace Renci.SshNet.Tests.Classes
             Assert.IsFalse(_subsystemSession.IsOpen);
         }
 
-        [TestMethod]
-        public void CloseOnChannelShouldBeInvokedOnce()
-        {
-            _channelMock.Verify(p => p.Close(), Times.Once);
-        }
-
         [TestMethod]
         public void DisposeOnChannelShouldBeInvokedOnce()
         {

+ 0 - 7
src/Renci.SshNet.Tests/Classes/SubsystemSession_Dispose_Disposed.cs

@@ -44,7 +44,6 @@ namespace Renci.SshNet.Tests.Classes
             _sessionMock.InSequence(sequence).Setup(p => p.CreateChannelSession()).Returns(_channelMock.Object);
             _channelMock.InSequence(sequence).Setup(p => p.Open());
             _channelMock.InSequence(sequence).Setup(p => p.SendSubsystemRequest(_subsystemName)).Returns(true);
-            _channelMock.InSequence(sequence).Setup(p => p.Close());
             _channelMock.InSequence(sequence).Setup(p => p.Dispose());
 
             _subsystemSession = new SubsystemSessionStub(
@@ -81,12 +80,6 @@ namespace Renci.SshNet.Tests.Classes
             Assert.IsFalse(_subsystemSession.IsOpen);
         }
 
-        [TestMethod]
-        public void CloseOnChannelShouldBeInvokedOnce()
-        {
-            _channelMock.Verify(p => p.Close(), Times.Once);
-        }
-
         [TestMethod]
         public void DisposeOnChannelShouldBeInvokedOnce()
         {

+ 0 - 6
src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelDataReceived_Connected.cs

@@ -106,12 +106,6 @@ namespace Renci.SshNet.Tests.Classes
             _channelMock.Verify(p => p.IsOpen, Times.Once);
         }
 
-        [TestMethod]
-        public void CloseOnChannelShouldNeverBeInvoked()
-        {
-            _channelMock.Verify(p => p.Close(), Times.Never);
-        }
-
         [TestMethod]
         public void DisposeOnChannelShouldNeverBeInvoked()
         {

+ 0 - 1
src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelDataReceived_Disposed.cs

@@ -48,7 +48,6 @@ namespace Renci.SshNet.Tests.Classes
             _sessionMock.InSequence(sequence).Setup(p => p.CreateChannelSession()).Returns(_channelMock.Object);
             _channelMock.InSequence(sequence).Setup(p => p.Open());
             _channelMock.InSequence(sequence).Setup(p => p.SendSubsystemRequest(_subsystemName)).Returns(true);
-            _channelMock.InSequence(sequence).Setup(p => p.Close());
             _channelMock.InSequence(sequence).Setup(p => p.Dispose());
 
             _subsystemSession = new SubsystemSessionStub(

+ 3 - 2
src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelDataReceived_OnDataReceived_Exception.cs

@@ -6,6 +6,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting;
 using Moq;
 using Renci.SshNet.Channels;
 using Renci.SshNet.Common;
+using Renci.SshNet.Tests.Common;
 
 namespace Renci.SshNet.Tests.Classes
 {
@@ -76,8 +77,8 @@ namespace Renci.SshNet.Tests.Classes
         [TestMethod]
         public void ErrorOccurredHaveFiredOnce()
         {
-            Assert.AreEqual(1, _errorOccurredRegister.Count);
-            Assert.AreSame(_onDataReceivedException, _errorOccurredRegister[0].Exception);
+            Assert.AreEqual(1, _errorOccurredRegister.Count, _errorOccurredRegister.AsString());
+            Assert.AreSame(_onDataReceivedException, _errorOccurredRegister[0].Exception, _errorOccurredRegister.AsString());
         }
 
         [TestMethod]

+ 3 - 8
src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelException_Connected.cs

@@ -6,6 +6,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting;
 using Moq;
 using Renci.SshNet.Channels;
 using Renci.SshNet.Common;
+using Renci.SshNet.Tests.Common;
 
 namespace Renci.SshNet.Tests.Classes
 {
@@ -72,8 +73,8 @@ namespace Renci.SshNet.Tests.Classes
         [TestMethod]
         public void ErrorOccurredHasFiredOnce()
         {
-            Assert.AreEqual(1, _errorOccurredRegister.Count);
-            Assert.AreSame(_channelExceptionEventArgs.Exception, _errorOccurredRegister[0].Exception);
+            Assert.AreEqual(1, _errorOccurredRegister.Count, _errorOccurredRegister.AsString());
+            Assert.AreSame(_channelExceptionEventArgs.Exception, _errorOccurredRegister[0].Exception, _errorOccurredRegister.AsString());
         }
 
         [TestMethod]
@@ -96,12 +97,6 @@ namespace Renci.SshNet.Tests.Classes
             _channelMock.Verify(p => p.IsOpen, Times.Exactly(1));
         }
 
-        [TestMethod]
-        public void CloseOnChannelShouldNeverBeInvoked()
-        {
-            _channelMock.Verify(p => p.Close(), Times.Never);
-        }
-
         [TestMethod]
         public void DisposeOnChannelShouldNeverBeInvoked()
         {

+ 0 - 1
src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelException_Disposed.cs

@@ -46,7 +46,6 @@ namespace Renci.SshNet.Tests.Classes
             _sessionMock.InSequence(sequence).Setup(p => p.CreateChannelSession()).Returns(_channelMock.Object);
             _channelMock.InSequence(sequence).Setup(p => p.Open());
             _channelMock.InSequence(sequence).Setup(p => p.SendSubsystemRequest(_subsystemName)).Returns(true);
-            _channelMock.InSequence(sequence).Setup(p => p.Close());
             _channelMock.InSequence(sequence).Setup(p => p.Dispose());
 
             _subsystemSession = new SubsystemSessionStub(

+ 0 - 6
src/Renci.SshNet.Tests/Classes/SubsystemSession_OnSessionDisconnected_Connected.cs

@@ -93,12 +93,6 @@ namespace Renci.SshNet.Tests.Classes
             _channelMock.Verify(p => p.IsOpen, Times.Exactly(1));
         }
 
-        [TestMethod]
-        public void CloseOnChannelShouldNeverBeInvoked()
-        {
-            _channelMock.Verify(p => p.Close(), Times.Never);
-        }
-
         [TestMethod]
         public void DisposeOnChannelShouldNeverBeInvoked()
         {

+ 0 - 1
src/Renci.SshNet.Tests/Classes/SubsystemSession_OnSessionDisconnected_Disposed.cs

@@ -44,7 +44,6 @@ namespace Renci.SshNet.Tests.Classes
             _sessionMock.InSequence(sequence).Setup(p => p.CreateChannelSession()).Returns(_channelMock.Object);
             _channelMock.InSequence(sequence).Setup(p => p.Open());
             _channelMock.InSequence(sequence).Setup(p => p.SendSubsystemRequest(_subsystemName)).Returns(true);
-            _channelMock.InSequence(sequence).Setup(p => p.Close());
             _channelMock.InSequence(sequence).Setup(p => p.Dispose());
 
             _subsystemSession = new SubsystemSessionStub(

+ 3 - 8
src/Renci.SshNet.Tests/Classes/SubsystemSession_OnSessionErrorOccurred_Connected.cs

@@ -6,6 +6,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting;
 using Moq;
 using Renci.SshNet.Channels;
 using Renci.SshNet.Common;
+using Renci.SshNet.Tests.Common;
 
 namespace Renci.SshNet.Tests.Classes
 {
@@ -72,8 +73,8 @@ namespace Renci.SshNet.Tests.Classes
         [TestMethod]
         public void ErrorOccurredHasFiredOnce()
         {
-            Assert.AreEqual(1, _errorOccurredRegister.Count);
-            Assert.AreSame(_errorOccurredEventArgs.Exception, _errorOccurredRegister[0].Exception);
+            Assert.AreEqual(1, _errorOccurredRegister.Count, _errorOccurredRegister.AsString());
+            Assert.AreSame(_errorOccurredEventArgs.Exception, _errorOccurredRegister[0].Exception, _errorOccurredRegister.AsString());
         }
 
         [TestMethod]
@@ -96,12 +97,6 @@ namespace Renci.SshNet.Tests.Classes
             _channelMock.Verify(p => p.IsOpen, Times.Exactly(1));
         }
 
-        [TestMethod]
-        public void CloseOnChannelShouldNeverBeInvoked()
-        {
-            _channelMock.Verify(p => p.Close(), Times.Never);
-        }
-
         [TestMethod]
         public void DisposeOnChannelShouldNeverBeInvoked()
         {

+ 0 - 1
src/Renci.SshNet.Tests/Classes/SubsystemSession_OnSessionErrorOccurred_Disposed.cs

@@ -46,7 +46,6 @@ namespace Renci.SshNet.Tests.Classes
             _sessionMock.InSequence(sequence).Setup(p => p.CreateChannelSession()).Returns(_channelMock.Object);
             _channelMock.InSequence(sequence).Setup(p => p.Open());
             _channelMock.InSequence(sequence).Setup(p => p.SendSubsystemRequest(_subsystemName)).Returns(true);
-            _channelMock.InSequence(sequence).Setup(p => p.Close());
             _channelMock.InSequence(sequence).Setup(p => p.Dispose());
 
             _subsystemSession = new SubsystemSessionStub(

+ 0 - 1
src/Renci.SshNet.Tests/Classes/SubsystemSession_SendData_Disposed.cs

@@ -45,7 +45,6 @@ namespace Renci.SshNet.Tests.Classes
             _sessionMock.InSequence(sequence).Setup(p => p.CreateChannelSession()).Returns(_channelMock.Object);
             _channelMock.InSequence(sequence).Setup(p => p.Open());
             _channelMock.InSequence(sequence).Setup(p => p.SendSubsystemRequest(_subsystemName)).Returns(true);
-            _channelMock.InSequence(sequence).Setup(p => p.Close());
             _channelMock.InSequence(sequence).Setup(p => p.Dispose());
 
             _subsystemSession = new SubsystemSessionStub(

+ 20 - 0
src/Renci.SshNet.Tests/Common/Extensions.cs

@@ -0,0 +1,20 @@
+using System.Collections.Generic;
+using Renci.SshNet.Common;
+
+namespace Renci.SshNet.Tests.Common
+{
+    internal static class Extensions
+    {
+        public static string AsString(this IList<ExceptionEventArgs> exceptionEvents)
+        {
+            if (exceptionEvents.Count == 0)
+                return string.Empty;
+
+            string reportedExceptions = string.Empty;
+            foreach (var exceptionEvent in exceptionEvents)
+                reportedExceptions += exceptionEvent.Exception.ToString();
+
+            return reportedExceptions;
+        }
+    }
+}

+ 21 - 20
src/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj

@@ -90,33 +90,33 @@
     </Compile>
     <Compile Include="Classes\BaseClientTest_Connected_KeepAlivesNotSentConcurrently.cs" />
     <Compile Include="Classes\Channels\ChannelDirectTcpipTest.cs" />
-    <Compile Include="Classes\Channels\ChannelDirectTcpipTest_Close_SessionIsConnectedAndChannelIsOpen.cs" />
-    <Compile Include="Classes\Channels\ChannelSessionTest_Close_Closed.cs" />
-    <Compile Include="Classes\Channels\ChannelSessionTest_Close_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_SendChannelCloseMessageFailure.cs" />
-    <Compile Include="Classes\Channels\ChannelSessionTest_Close_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_SendChannelCloseMessageSuccess.cs" />
-    <Compile Include="Classes\Channels\ChannelSessionTest_Close_SessionIsConnectedAndChannelIsOpen_ChannelCloseReceived_SendChannelCloseMessageFailure.cs" />
-    <Compile Include="Classes\Channels\ChannelSessionTest_Close_SessionIsConnectedAndChannelIsOpen_ChannelCloseReceived_SendChannelCloseMessageSuccess.cs" />
-    <Compile Include="Classes\Channels\ChannelSessionTest_Close_SessionIsConnectedAndChannelIsOpen_ChannelEofReceived_SendChannelCloseMessageFailure.cs" />
-    <Compile Include="Classes\Channels\ChannelSessionTest_Close_SessionIsConnectedAndChannelIsOpen_ChannelEofReceived_SendChannelCloseMessageSuccess.cs" />
-    <Compile Include="Classes\Channels\ChannelSessionTest_Close_SessionIsConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived_SendChannelEofMessageFailure.cs" />
-    <Compile Include="Classes\Channels\ChannelSessionTest_Close_SessionIsNotConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived.cs" />
-    <Compile Include="Classes\Channels\ChannelSessionTest_Close_SessionIsNotConnectedAndChannelIsOpen_ChannelCloseReceived.cs" />
-    <Compile Include="Classes\Channels\ChannelSessionTest_Close_SessionIsNotConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived.cs" />
+    <Compile Include="Classes\Channels\ChannelDirectTcpipTest_Dispose_SessionIsConnectedAndChannelIsOpen.cs" />
+    <Compile Include="Classes\Channels\ChannelSessionTest_Dispose_Disposed.cs" />
+    <Compile Include="Classes\Channels\ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_SendChannelCloseMessageFailure.cs" />
+    <Compile Include="Classes\Channels\ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_SendChannelCloseMessageSuccess.cs" />
+    <Compile Include="Classes\Channels\ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseReceived_SendChannelCloseMessageFailure.cs" />
+    <Compile Include="Classes\Channels\ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseReceived_SendChannelCloseMessageSuccess.cs" />
+    <Compile Include="Classes\Channels\ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelEofReceived_SendChannelCloseMessageFailure.cs" />
+    <Compile Include="Classes\Channels\ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelEofReceived_SendChannelCloseMessageSuccess.cs" />
+    <Compile Include="Classes\Channels\ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived_SendChannelEofMessageFailure.cs" />
+    <Compile Include="Classes\Channels\ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived.cs" />
+    <Compile Include="Classes\Channels\ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_ChannelCloseReceived.cs" />
+    <Compile Include="Classes\Channels\ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived.cs" />
     <Compile Include="Classes\Channels\ChannelSessionTest_Disposed_Closed.cs" />
     <Compile Include="Classes\Channels\ChannelSessionTest_OnSessionChannelCloseReceived_SessionIsConnectedAndChannelIsOpen.cs" />
-    <Compile Include="Classes\Channels\ChannelSessionTest_Close_SessionIsConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived.cs" />
+    <Compile Include="Classes\Channels\ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived.cs" />
     <Compile Include="Classes\Channels\ChannelSessionTest_Open_ExceptionWaitingOnOpenConfirmation.cs" />
     <Compile Include="Classes\Channels\ChannelSessionTest_Open_OnOpenFailureReceived_NoRetriesAvailable.cs" />
     <Compile Include="Classes\Channels\ChannelSessionTest_Open_OnOpenFailureReceived_RetriesAvalable.cs" />
-    <Compile Include="Classes\Channels\ChannelTest_Close_SessionIsConnectedAndChannelIsOpen_EofNotReceived_SendEofInvoked.cs" />
-    <Compile Include="Classes\Channels\ChannelTest_Close_SessionIsConnectedAndChannelIsOpen_EofReceived.cs" />
-    <Compile Include="Classes\Channels\ChannelTest_Close_SessionIsNotConnectedAndChannelIsOpen.cs" />
+    <Compile Include="Classes\Channels\ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofNotReceived_SendEofInvoked.cs" />
+    <Compile Include="Classes\Channels\ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofReceived.cs" />
+    <Compile Include="Classes\Channels\ChannelTest_Dispose_SessionIsNotConnectedAndChannelIsOpen.cs" />
     <Compile Include="Classes\Channels\ChannelTest_OnSessionChannelCloseReceived_OnClose_Exception.cs" />
     <Compile Include="Classes\Channels\ChannelTest_OnSessionChannelCloseReceived_SessionIsConnectedAndChannelIsOpen_EofReceived.cs" />
     <Compile Include="Classes\Channels\ChannelTest_OnSessionChannelDataReceived_OnData_Exception.cs" />
-    <Compile Include="Classes\Channels\ChannelTest_Close_SessionIsConnectedAndChannelIsOpen_EofNotReceived.cs" />
-    <Compile Include="Classes\Channels\ChannelTest_Close_SessionIsConnectedAndChannelIsNotOpen.cs" />
-    <Compile Include="Classes\Channels\ChannelTest_Close_SessionIsNotConnectedAndChannelIsNotOpen.cs" />
+    <Compile Include="Classes\Channels\ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofNotReceived.cs" />
+    <Compile Include="Classes\Channels\ChannelTest_Dispose_SessionIsConnectedAndChannelIsNotOpen.cs" />
+    <Compile Include="Classes\Channels\ChannelTest_Dispose_SessionIsNotConnectedAndChannelIsNotOpen.cs" />
     <Compile Include="Classes\Channels\ChannelTest_OnSessionChannelCloseReceived_SessionIsConnectedAndChannelIsOpen_EofNotReceived.cs" />
     <Compile Include="Classes\Channels\ChannelTest_OnSessionChannelEofReceived_OnEof_Exception.cs" />
     <Compile Include="Classes\Channels\ChannelTest_OnSessionChannelExtendedDataReceived_OnExtendedData_Exception.cs" />
@@ -238,7 +238,7 @@
     <Compile Include="Classes\Common\AuthenticationPromptEventArgsTest.cs" />
     <Compile Include="Classes\Common\AuthenticationPromptTest.cs" />
     <Compile Include="Classes\Common\BigIntegerTest.cs" />
-    <Compile Include="Classes\Channels\ChannelForwardedTcpipTest_Close_SessionIsConnectedAndChannelIsOpen.cs" />
+    <Compile Include="Classes\Channels\ChannelForwardedTcpipTest_Dispose_SessionIsConnectedAndChannelIsOpen.cs" />
     <Compile Include="Classes\CommandAsyncResultTest.cs" />
     <Compile Include="Classes\Common\ASCIIEncodingTest.cs" />
     <Compile Include="Classes\Common\ChannelDataEventArgsTest.cs" />
@@ -458,6 +458,7 @@
     <Compile Include="Classes\SubsystemSession_SendData_Disposed.cs" />
     <Compile Include="Classes\SubsystemSession_SendData_NeverConnected.cs" />
     <Compile Include="Common\AsyncSocketListener.cs" />
+    <Compile Include="Common\Extensions.cs" />
     <Compile Include="Common\HttpProxyStub.cs" />
     <Compile Include="Common\HttpRequest.cs" />
     <Compile Include="Classes\Common\PipeStream_Close_BlockingRead.cs" />

+ 65 - 86
src/Renci.SshNet/Channels/Channel.cs

@@ -13,10 +13,6 @@ namespace Renci.SshNet.Channels
     /// </summary>
     internal abstract class Channel : IChannel
     {
-        private const int Initial = 0;
-        private const int Considered = 1;
-        private const int Sent = 2;
-
         private EventWaitHandle _channelClosedWaitHandle = new ManualResetEvent(false);
         private EventWaitHandle _channelServerWindowAdjustWaitHandle = new ManualResetEvent(false);
         private EventWaitHandle _errorOccuredWaitHandle = new ManualResetEvent(false);
@@ -31,11 +27,10 @@ namespace Renci.SshNet.Channels
         /// Holds a value indicating whether the SSH_MSG_CHANNEL_CLOSE has been sent to the remote party.
         /// </summary>
         /// <value>
-        /// <c>0</c> when the SSH_MSG_CHANNEL_CLOSE message has not been sent or considered
-        /// <c>1</c> when sending a SSH_MSG_CHANNEL_CLOSE message to the remote party is under consideration
-        /// <c>2</c> when this message has been sent to the remote party
+        /// <c>true</c> when a SSH_MSG_CHANNEL_CLOSE message has been sent to the other party;
+        /// otherwise, <c>false</c>.
         /// </value>
-        private int _closeMessageSent;
+        private bool _closeMessageSent;
 
         /// <summary>
         /// Holds a value indicating whether a SSH_MSG_CHANNEL_CLOSE has been received from the other
@@ -60,11 +55,10 @@ namespace Renci.SshNet.Channels
         /// Holds a value indicating whether the SSH_MSG_CHANNEL_EOF has been sent to the remote party.
         /// </summary>
         /// <value>
-        /// <c>0</c> when the SSH_MSG_CHANNEL_EOF message has not been sent or considered
-        /// <c>1</c> when sending a SSH_MSG_CHANNEL_EOF message to the remote party is under consideration
-        /// <c>2</c> when this message has been sent to the remote party
+        /// <c>true</c> when a SSH_MSG_CHANNEL_EOF message has been sent to the remote party;
+        /// otherwise, <c>false</c>.
         /// </value>
-        private int _eofMessageSent;
+        private bool _eofMessageSent;
 
         /// <summary>
         /// Occurs when an exception is thrown when processing channel messages.
@@ -86,16 +80,16 @@ namespace Renci.SshNet.Channels
             LocalPacketSize = localPacketSize;
             LocalWindowSize = localWindowSize;
 
-            _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.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>
@@ -336,14 +330,6 @@ namespace Renci.SshNet.Channels
             }
         }
 
-        /// <summary>
-        /// Closes the channel.
-        /// </summary>
-        public void Close()
-        {
-            Close(true);
-        }
-
         #region Channel virtual methods
 
         /// <summary>
@@ -405,9 +391,15 @@ namespace Renci.SshNet.Channels
         {
             _closeMessageReceived = true;
 
+            // signal that SSH_MSG_CHANNEL_CLOSE message was received from server
+            var channelClosedWaitHandle = _channelClosedWaitHandle;
+            if (channelClosedWaitHandle != null)
+                channelClosedWaitHandle.Set();
+
             // close the channel
-            Close(false);
+            Close();
 
+            // raise event signaling that the server has closed the channel
             var closed = Closed;
             if (closed != null)
                 closed(this, new ChannelEventArgs(LocalChannelNumber));
@@ -498,8 +490,11 @@ namespace Renci.SshNet.Channels
             if (!IsOpen)
                 throw CreateChannelClosedException();
 
-            _session.SendMessage(new ChannelEofMessage(RemoteChannelNumber));
-            _eofMessageSent = Sent;
+            lock (this)
+            {
+                _session.SendMessage(new ChannelEofMessage(RemoteChannelNumber));
+                _eofMessageSent = true;
+            }
         }
 
         /// <summary>
@@ -512,66 +507,54 @@ namespace Renci.SshNet.Channels
         }
 
         /// <summary>
-        /// Closes the channel, optionally waiting for the SSH_MSG_CHANNEL_CLOSE message to
-        /// be received from the server.
+        /// Closes the channel, waiting for the SSH_MSG_CHANNEL_CLOSE message to be received from the server.
         /// </summary>
-        /// <param name="wait"><c>true</c> to wait for the SSH_MSG_CHANNEL_CLOSE message to be received from the server; otherwise, <c>false</c>.</param>
-        protected virtual void Close(bool wait)
+        protected virtual void Close()
         {
-            // send EOF message first when channel need to be closed, and the remote party has not already sent
-            // a SSH_MSG_CHANNEL_EOF or SSH_MSG_CHANNEL_CLOSE message
-            //
-            // note that we might have had a race condition here when the remote party sends a SSH_MSG_CHANNEL_CLOSE
-            // immediately after it has sent a SSH_MSG_CHANNEL_EOF message
-            //
-            // in that case, we would risk sending a SSH_MSG_CHANNEL_EOF message after the remote party has
-            // closed its end of the channel
-            //
-            // as a solution for this issue we only send a SSH_MSG_CHANNEL_EOF message if we haven't received a
-            // SSH_MSG_CHANNEL_EOF or SSH_MSG_CHANNEL_CLOSE message from the remote party
-            if (Interlocked.CompareExchange(ref _eofMessageSent, Considered, Initial) == Initial)
+            // synchronize sending SSH_MSG_CHANNEL_EOF and SSH_MSG_CHANNEL_CLOSE to ensure that these messages
+            // are sent in that other; when both the client and the server attempt to close the channel at the
+            // same time we would otherwise risk sending the SSH_MSG_CHANNEL_EOF after the SSH_MSG_CHANNEL_CLOSE
+            // message causing the server to disconnect the session.
+
+            lock (this)
             {
-                if (!_closeMessageReceived && !_eofMessageReceived && IsOpen && IsConnected)
+                // send EOF message first the following conditions are met:
+                // * we have not sent a SSH_MSG_CHANNEL_EOF message
+                // * remote party has not already sent a SSH_MSG_CHANNEL_EOF message
+                // * remote party has not already sent a SSH_MSG_CHANNEL_CLOSE message
+                // * the channel is open
+                // * the session is connected
+                if (!_eofMessageSent && !_closeMessageReceived && !_eofMessageReceived && IsOpen && IsConnected)
                 {
                     if (TrySendMessage(new ChannelEofMessage(RemoteChannelNumber)))
-                        _eofMessageSent = Sent;
+                    {
+                        _eofMessageSent = true;
+                    }
                 }
-            }
 
-            // send message to close the channel on the server
-            if (Interlocked.CompareExchange(ref _closeMessageSent, Considered, Initial) == Initial)
-            {
-                // ignore sending close message when client is not connected or the channel is closed
-                if (IsOpen && IsConnected)
+                // send message to close the channel on the server when it has not already been sent
+                // and the channel is open and the session is connected
+                if (!_closeMessageSent && IsOpen && IsConnected)
                 {
                     if (TrySendMessage(new ChannelCloseMessage(RemoteChannelNumber)))
-                        _closeMessageSent = Sent;
+                    {
+                        _closeMessageSent = true;
+
+                        // wait for channel to be closed if we actually sent a close message (either to initiate closing
+                        // the channel, or as response to a SSH_MSG_CHANNEL_CLOSE message sent by the server
+                        try
+                        {
+                            WaitOnHandle(_channelClosedWaitHandle);
+                        }
+                        catch (SshConnectionException)
+                        {
+                            // ignore connection failures as we're closing the channel anyway
+                        }
+                    }
                 }
-            }
-
-            // mark the channel closed
-            IsOpen = false;
 
-            // wait for channel to be closed if we actually sent a close message (either to initiate closing
-            // the channel, or as response to a SSH_MSG_CHANNEL_CLOSE message sent by the server
-            if (wait && _closeMessageSent == Sent)
-            {
-                try
-                {
-                    WaitOnHandle(_channelClosedWaitHandle);
-                }
-                catch (SshConnectionException)
-                {
-                    // ignore connection failures as we're closing the channel anyway
-                }
+                IsOpen = false;
             }
-
-            // reset indicators in case we want to reopen the channel; these are safe to reset
-            // since the channel is marked closed by now
-            _eofMessageSent = Initial;
-            _eofMessageReceived = false;
-            _closeMessageReceived = false;
-            _closeMessageSent = Initial;
         }
 
         protected virtual void OnDisconnected()
@@ -700,10 +683,6 @@ namespace Renci.SshNet.Channels
                 {
                     OnChannelException(ex);
                 }
-
-                var channelClosedWaitHandle = _channelClosedWaitHandle;
-                if (channelClosedWaitHandle != null)
-                    channelClosedWaitHandle.Set();
             }
         }
 
@@ -846,7 +825,7 @@ namespace Renci.SshNet.Channels
 
             if (disposing)
             {
-                Close(false);
+                Close();
 
                 var session = _session;
                 if (session != null)

+ 4 - 6
src/Renci.SshNet/Channels/ChannelDirectTcpip.cs

@@ -137,11 +137,9 @@ namespace Renci.SshNet.Channels
         }
 
         /// <summary>
-        /// Closes the channel, optionally waiting for the SSH_MSG_CHANNEL_CLOSE message to
-        /// be received from the server.
+        /// Closes the channel, waiting for the SSH_MSG_CHANNEL_CLOSE message to be received from the server.
         /// </summary>
-        /// <param name="wait"><c>true</c> to wait for the SSH_MSG_CHANNEL_CLOSE message to be received from the server; otherwise, <c>false</c>.</param>
-        protected override void Close(bool wait)
+        protected override void Close()
         {
             var forwardedPort = _forwardedPort;
             if (forwardedPort != null)
@@ -156,8 +154,8 @@ namespace Renci.SshNet.Channels
             // if the FIN/ACK is not sent in time, the socket will be closed after the channel is closed
             ShutdownSocket(SocketShutdown.Send);
 
-            // close the SSH channel, and mark the channel closed
-            base.Close(wait);
+            // close the SSH channel
+            base.Close();
 
             // close the socket
             CloseSocket();

+ 3 - 5
src/Renci.SshNet/Channels/ChannelForwardedTcpip.cs

@@ -142,11 +142,9 @@ namespace Renci.SshNet.Channels
         }
 
         /// <summary>
-        /// Closes the channel, optionally waiting for the SSH_MSG_CHANNEL_CLOSE message to
-        /// be received from the server.
+        /// Closes the channel waiting for the SSH_MSG_CHANNEL_CLOSE message to be received from the server.
         /// </summary>
-        /// <param name="wait"><c>true</c> to wait for the SSH_MSG_CHANNEL_CLOSE message to be received from the server; otherwise, <c>false</c>.</param>
-        protected override void Close(bool wait)
+        protected override void Close()
         {
             var forwardedPort = _forwardedPort;
             if (forwardedPort != null)
@@ -162,7 +160,7 @@ namespace Renci.SshNet.Channels
             ShutdownSocket(SocketShutdown.Send);
 
             // close the SSH channel, and mark the channel closed
-            base.Close(wait);
+            base.Close();
 
             // close the socket
             CloseSocket();

+ 2 - 15
src/Renci.SshNet/Channels/ChannelSession.cs

@@ -113,22 +113,9 @@ namespace Renci.SshNet.Channels
             _channelOpenResponseWaitHandle.Set();
         }
 
-        /// <summary>
-        /// Called when channel is closed by the server.
-        /// </summary>
-        protected override void OnClose()
+        protected override void Close()
         {
-            base.OnClose();
-
-            //  This timeout needed since when channel is closed it does not immediately becomes available
-            //  but it takes time for the server to clean up resource and allow new channels to be created.
-            ThreadAbstraction.Sleep(100);
-        }
-
-        protected override void Close(bool wait)
-        {
-            base.Close(wait);
-
+            base.Close();
             ReleaseSemaphore();
         }
 

+ 0 - 5
src/Renci.SshNet/Channels/IChannel.cs

@@ -60,11 +60,6 @@ namespace Renci.SshNet.Channels
         /// <exception cref="InvalidOperationException">The channel has not been opened, or the open has not yet been confirmed.</exception>
         uint RemotePacketSize { get; }
 
-        /// <summary>
-        /// Closes the channel.
-        /// </summary>
-        void Close();
-
         /// <summary>
         /// Gets a value indicating whether this channel is open.
         /// </summary>

+ 0 - 5
src/Renci.SshNet/Channels/IChannelDirectTcpip.cs

@@ -43,10 +43,5 @@ namespace Renci.SshNet.Channels
         /// Binds the channel to the remote host.
         /// </summary>
         void Bind();
-
-        /// <summary>
-        /// Closes the channel.
-        /// </summary>
-        void Close();
     }
 }

+ 0 - 5
src/Renci.SshNet/Channels/IChannelForwardedTcpip.cs

@@ -20,10 +20,5 @@ namespace Renci.SshNet.Channels
         /// <param name="remoteEndpoint">The endpoint to connect to.</param>
         /// <param name="forwardedPort">The forwarded port for which the channel is opened.</param>
         void Bind(IPEndPoint remoteEndpoint, IForwardedPort forwardedPort);
-
-        /// <summary>
-        /// Closes the channel.
-        /// </summary>
-        void Close();
     }
 }

+ 6 - 13
src/Renci.SshNet/ForwardedPortDynamic.NET.cs

@@ -124,21 +124,14 @@ namespace Renci.SshNet
                 {
                     channel.Exception += Channel_Exception;
 
-                    try
+                    if (!HandleSocks(channel, clientSocket, Session.ConnectionInfo.Timeout))
                     {
-                        if (!HandleSocks(channel, clientSocket, Session.ConnectionInfo.Timeout))
-                        {
-                            CloseClientSocket(clientSocket);
-                            return;
-                        }
-
-                        // start receiving from client socket (and sending to server)
-                        channel.Bind();
-                    }
-                    finally
-                    {
-                        channel.Close();
+                        CloseClientSocket(clientSocket);
+                        return;
                     }
+
+                    // start receiving from client socket (and sending to server)
+                    channel.Bind();
                 }
             }
             catch (Exception exp)

+ 0 - 1
src/Renci.SshNet/ForwardedPortLocal.NET.cs

@@ -125,7 +125,6 @@ namespace Renci.SshNet
                     channel.Exception += Channel_Exception;
                     channel.Open(Host, Port, this, clientSocket);
                     channel.Bind();
-                    channel.Close();
                 }
             }
             catch (Exception exp)

+ 0 - 1
src/Renci.SshNet/ForwardedPortRemote.cs

@@ -251,7 +251,6 @@ namespace Renci.SshNet
                                 {
                                     channel.Exception += Channel_Exception;
                                     channel.Bind(new IPEndPoint(HostAddress, (int) Port), this);
-                                    channel.Close();
                                 }
                             }
                             catch (Exception exp)

+ 15 - 0
src/Renci.SshNet/ISession.cs

@@ -141,6 +141,21 @@ namespace Renci.SshNet
         /// </remarks>
         void WaitOnHandle(WaitHandle waitHandle);
 
+        /// <summary>
+        /// Waits for the specified handle or the exception handle for the receive thread
+        /// to signal within the specified timeout.
+        /// </summary>
+        /// <param name="waitHandle">The wait handle.</param>
+        /// <param name="timeout">The time to wait for any of the handles to become signaled.</param>
+        /// <exception cref="SshConnectionException">A received package was invalid or failed the message integrity check.</exception>
+        /// <exception cref="SshOperationTimeoutException">None of the handles are signaled in time and the session is not disconnecting.</exception>
+        /// <exception cref="SocketException">A socket error was signaled while receiving messages from the server.</exception>
+        /// <remarks>
+        /// When neither handles are signaled in time and the session is not closing, then the
+        /// session is disconnected.
+        /// </remarks>
+        void WaitOnHandle(WaitHandle waitHandle, TimeSpan timeout);
+
         /// <summary>
         /// Occurs when <see cref="ChannelCloseMessage"/> message received
         /// </summary>

+ 0 - 8
src/Renci.SshNet/ScpClient.NET.cs

@@ -40,8 +40,6 @@ namespace Renci.SshNet
                 CheckReturnCode(input);
 
                 InternalUpload(channel, input, fileInfo, fileInfo.Name);
-
-                channel.Close();
             }
         }
 
@@ -77,8 +75,6 @@ namespace Renci.SshNet
 
                 SendData(channel, "E\n");
                 CheckReturnCode(input);
-
-                channel.Close();
             }
         }
 
@@ -107,8 +103,6 @@ namespace Renci.SshNet
                 SendConfirmation(channel); //  Send reply
 
                 InternalDownload(channel, input, fileInfo);
-
-                channel.Close();
             }
         }
 
@@ -137,8 +131,6 @@ namespace Renci.SshNet
                 SendConfirmation(channel); //  Send reply
 
                 InternalDownload(channel, input, directoryInfo);
-
-                channel.Close();
             }
         }
 

+ 0 - 4
src/Renci.SshNet/ScpClient.cs

@@ -187,8 +187,6 @@ namespace Renci.SshNet
                 }
 
                 InternalUpload(channel, input, source, path);
-
-                channel.Close();
             }
         }
 
@@ -239,8 +237,6 @@ namespace Renci.SshNet
                 {
                     SendConfirmation(channel, 1, string.Format("\"{0}\" is not valid protocol message.", message));
                 }
-
-                channel.Close();
             }
         }
 

+ 20 - 2
src/Renci.SshNet/Session.cs

@@ -722,7 +722,25 @@ namespace Renci.SshNet
         /// </remarks>
         void ISession.WaitOnHandle(WaitHandle waitHandle)
         {
-            WaitOnHandle(waitHandle);
+            WaitOnHandle(waitHandle, ConnectionInfo.Timeout);
+        }
+
+        /// <summary>
+        /// Waits for the specified handle or the exception handle for the receive thread
+        /// to signal within the specified timeout.
+        /// </summary>
+        /// <param name="waitHandle">The wait handle.</param>
+        /// <param name="timeout">The time to wait for any of the handles to become signaled.</param>
+        /// <exception cref="SshConnectionException">A received package was invalid or failed the message integrity check.</exception>
+        /// <exception cref="SshOperationTimeoutException">None of the handles are signaled in time and the session is not disconnecting.</exception>
+        /// <exception cref="SocketException">A socket error was signaled while receiving messages from the server.</exception>
+        /// <remarks>
+        /// When neither handles are signaled in time and the session is not closing, then the
+        /// session is disconnected.
+        /// </remarks>
+        void ISession.WaitOnHandle(WaitHandle waitHandle, TimeSpan timeout)
+        {
+            WaitOnHandle(waitHandle, timeout);
         }
 
         /// <summary>
@@ -1929,7 +1947,7 @@ namespace Renci.SshNet
                 var readSockets = new List<Socket> {_socket};
 
                 // remain in message loop until socket is shut down or until we're disconnecting
-                while (!_isDisconnecting)
+                while (true)
                 {
 #if FEATURE_SOCKET_POLL
                     Socket.Select(readSockets, null, null, -1);

+ 2 - 6
src/Renci.SshNet/Shell.cs

@@ -191,7 +191,7 @@ namespace Renci.SshNet
 
             if (_channel != null)
             {
-                _channel.Close();
+                _channel.Dispose();
             }
         }
 
@@ -238,11 +238,7 @@ namespace Renci.SshNet
                 ThreadAbstraction.ExecuteThread(() => Stopping(this, new EventArgs()));
             }
 
-            if (_channel.IsOpen)
-            {
-                _channel.Close();
-            }
-
+            _channel.Dispose();
             _channelClosedWaitHandle.Set();
 
             _input.Dispose();

+ 1 - 1
src/Renci.SshNet/ShellStream.cs

@@ -723,7 +723,7 @@ namespace Renci.SshNet
         private void Session_Disconnected(object sender, EventArgs e)
         {
             if (_channel != null)
-                _channel.Close();
+                _channel.Dispose();
         }
 
         private void Channel_Closed(object sender, ChannelEventArgs e)

+ 1 - 6
src/Renci.SshNet/SshCommand.cs

@@ -310,11 +310,6 @@ namespace Renci.SshNet
                 //  wait for operation to complete (or time out)
                 WaitOnHandle(_asyncResult.AsyncWaitHandle);
 
-                if (_channel.IsOpen)
-                {
-                    _channel.Close();
-                }
-
                 UnsubscribeFromEventsAndDisposeChannel(_channel);
                 _channel = null;
 
@@ -348,7 +343,7 @@ namespace Renci.SshNet
             if (_channel != null && _channel.IsOpen && _asyncResult != null)
             {
                 // TODO: check with Oleg if we shouldn't dispose the channel and uninitialize it ?
-                _channel.Close();
+                _channel.Dispose();
             }
         }
 

+ 0 - 1
src/Renci.SshNet/SubsystemSession.cs

@@ -134,7 +134,6 @@ namespace Renci.SshNet
                 channel.DataReceived -= Channel_DataReceived;
                 channel.Exception -= Channel_Exception;
                 channel.Closed -= Channel_Closed;
-                channel.Close();
                 channel.Dispose();
                 _channel = null;
             }