@@ -54,21 +54,51 @@ public static Socket Connect(IPEndPoint remoteEndpoint, TimeSpan connectTimeout)
54
54
#if FEATURE_SOCKET_EAP
55
55
var connectCompleted = new ManualResetEvent ( false ) ;
56
56
var args = new SocketAsyncEventArgs
57
- {
58
- UserToken = connectCompleted ,
59
- RemoteEndPoint = remoteEndpoint
60
- } ;
57
+ {
58
+ UserToken = connectCompleted ,
59
+ RemoteEndPoint = remoteEndpoint
60
+ } ;
61
61
args . Completed += ConnectCompleted ;
62
62
63
63
if ( socket . ConnectAsync ( args ) )
64
64
{
65
65
if ( ! connectCompleted . WaitOne ( connectTimeout ) )
66
+ {
67
+ // avoid ObjectDisposedException in ConnectCompleted
68
+ args . Completed -= ConnectCompleted ;
69
+ // avoid leaking threads and /Device/Afd handles
70
+ Socket . CancelConnectAsync ( args ) ;
71
+ // dispose Socket
72
+ socket . Dispose ( ) ;
73
+ // dispose ManualResetEvent
74
+ connectCompleted . Dispose ( ) ;
75
+ // dispose SocketAsyncEventArgs
76
+ args . Dispose ( ) ;
77
+
66
78
throw new SshOperationTimeoutException ( string . Format ( CultureInfo . InvariantCulture ,
67
- "Connection failed to establish within {0:F0} milliseconds." , connectTimeout . TotalMilliseconds ) ) ;
79
+ "Connection failed to establish within {0:F0} milliseconds." ,
80
+ connectTimeout . TotalMilliseconds ) ) ;
81
+ }
68
82
}
69
83
84
+ // dispose ManualResetEvent
85
+ connectCompleted . Dispose ( ) ;
86
+
70
87
if ( args . SocketError != SocketError . Success )
71
- throw new SocketException ( ( int ) args . SocketError ) ;
88
+ {
89
+ var socketError = ( int ) args . SocketError ;
90
+
91
+ // dispose Socket
92
+ socket . Dispose ( ) ;
93
+ // dispose SocketAsyncEventArgs
94
+ args . Dispose ( ) ;
95
+
96
+ throw new SocketException ( socketError ) ;
97
+ }
98
+
99
+ // dispose SocketAsyncEventArgs
100
+ args . Dispose ( ) ;
101
+
72
102
return socket ;
73
103
#elif FEATURE_SOCKET_APM
74
104
var connectResult = socket . BeginConnect ( remoteEndpoint , null , null ) ;
0 commit comments