@@ -181,6 +181,11 @@ public void Connect(EndPoint endPoint)
181181 {
182182 HandleCommunicationError ( _socket , ex ) ;
183183 }
184+ catch ( ObjectDisposedException )
185+ {
186+ // If disposed, handle communication error was already done and we're just catching up on other threads. Supress it.
187+ return ;
188+ }
184189
185190 // Get a message state from the pool
186191 var messageState = _messageStatePool . Pop ( ) ;
@@ -222,7 +227,7 @@ public void Listen(EndPoint localEndpoint)
222227
223228 // Create socket
224229 _socket = _socketFunc ( ) ;
225-
230+
226231 try
227232 {
228233 _socket . Bind ( localEndpoint ) ;
@@ -234,7 +239,10 @@ public void Listen(EndPoint localEndpoint)
234239 catch ( SocketException ex )
235240 {
236241 HandleCommunicationError ( _socket , ex ) ;
237- return ;
242+ }
243+ catch ( ObjectDisposedException )
244+ {
245+ // If disposed, handle communication error was already done and we're just catching up on other threads. Supress it.
238246 }
239247 }
240248
@@ -288,6 +296,11 @@ public void Send(byte[] message)
288296 {
289297 HandleCommunicationError ( _socket , ex ) ;
290298 }
299+ catch ( ObjectDisposedException )
300+ {
301+ // If disposed, handle communication error was already done and we're just catching up on other threads. Supress it.
302+ return ;
303+ }
291304 }
292305
293306 /// <summary>
@@ -324,6 +337,11 @@ public byte[] SendReceive(byte[] message)
324337 HandleCommunicationError ( _socket , ex ) ;
325338 return null ;
326339 }
340+ catch ( ObjectDisposedException )
341+ {
342+ // If disposed, handle communication error was already done and we're just catching up on other threads. Supress it.
343+ return null ;
344+ }
327345
328346 // Wait for our message to go ahead from the receive callback
329347 multiplexerData . ManualResetEvent . WaitOne ( ) ;
@@ -370,6 +388,11 @@ public void Reply(byte[] message, ReceivedMessage receivedMessage)
370388 HandleCommunicationError ( receivedMessage . Socket , ex ) ;
371389 return ;
372390 }
391+ catch ( ObjectDisposedException )
392+ {
393+ // If disposed, handle communication error was already done and we're just catching up on other threads. Supress it.
394+ return ;
395+ }
373396
374397 // Put received message back in the pool
375398 _receiveMessagePool . Push ( receivedMessage ) ;
@@ -409,6 +432,12 @@ private void AcceptCallback(IAsyncResult asyncResult)
409432 HandleCommunicationError ( _socket , ex ) ;
410433 return ;
411434 }
435+ catch ( ObjectDisposedException )
436+ {
437+ // If disposed, handle communication error was already done and we're just catching up on other threads. Supress it.
438+ return ;
439+ }
440+
412441 // Turn on or off Nagle algorithm
413442 handler . NoDelay = ! _useNagleAlgorithm ;
414443
@@ -422,6 +451,11 @@ private void AcceptCallback(IAsyncResult asyncResult)
422451 HandleCommunicationError ( _socket , ex ) ;
423452 return ;
424453 }
454+ catch ( ObjectDisposedException )
455+ {
456+ // If disposed, handle communication error was already done and we're just catching up on other threads. Supress it.
457+ return ;
458+ }
425459
426460 // Do not proceed until we have room to do so
427461 _maxConnectionsSemaphore . WaitOne ( ) ;
@@ -442,6 +476,11 @@ private void AcceptCallback(IAsyncResult asyncResult)
442476 HandleCommunicationError ( handler , ex ) ;
443477 return ;
444478 }
479+ catch ( ObjectDisposedException )
480+ {
481+ // If disposed, handle communication error was already done and we're just catching up on other threads. Supress it.
482+ return ;
483+ }
445484
446485 // Create receive queue for this client
447486 _receiveBufferQueueLock . EnterWriteLock ( ) ;
@@ -473,6 +512,11 @@ private void SendCallback(IAsyncResult asyncResult)
473512 HandleCommunicationError ( socket , ex ) ;
474513 return ;
475514 }
515+ catch ( ObjectDisposedException )
516+ {
517+ // If disposed, handle communication error was already done and we're just catching up on other threads. Supress it.
518+ return ;
519+ }
476520 }
477521
478522 private void ReceiveCallback ( IAsyncResult asyncResult )
@@ -493,6 +537,11 @@ private void ReceiveCallback(IAsyncResult asyncResult)
493537 HandleCommunicationError ( messageState . Handler , ex ) ;
494538 return ;
495539 }
540+ catch ( ObjectDisposedException )
541+ {
542+ // If disposed, handle communication error was already done and we're just catching up on other threads. Supress it.
543+ return ;
544+ }
496545
497546 if ( bytesRead > 0 )
498547 {
@@ -522,7 +571,10 @@ private void ReceiveCallback(IAsyncResult asyncResult)
522571 catch ( SocketException ex )
523572 {
524573 HandleCommunicationError ( messageState . Handler , ex ) ;
525- return ;
574+ }
575+ catch ( ObjectDisposedException )
576+ {
577+ // If disposed, handle communication error was already done and we're just catching up on other threads. Supress it.
526578 }
527579 }
528580 }
@@ -664,17 +716,26 @@ private void ProcessReceivedMessage(MessageState messageState)
664716 /// <param name="ex">The exception that the socket raised.</param>
665717 private void HandleCommunicationError ( Socket socket , Exception ex )
666718 {
667- // Close the socket
668- try
719+ lock ( socket )
669720 {
670- socket . Shutdown ( SocketShutdown . Both ) ;
671- }
672- catch
673- {
674- // Ignore
675- }
721+ // Close the socket
722+ try
723+ {
724+ socket . Shutdown ( SocketShutdown . Both ) ;
725+ }
726+ catch ( ObjectDisposedException )
727+ {
728+ // Socket was already closed/disposed, so return out to prevent raising the Error event multiple times
729+ // This is most likely to happen when an error occurs during heavily multithreaded use
730+ return ;
731+ }
732+ catch
733+ {
734+ // Ignore
735+ }
676736
677- socket . Close ( ) ;
737+ socket . Close ( ) ;
738+ }
678739
679740 // Release all multiplexer clients by signalling them
680741 _clientMultiplexerLock . EnterReadLock ( ) ;
0 commit comments