/// <summary> /// This method is called when there is no more data to send to a connected client /// </summary> private void OnSocketSend(object sender, SocketAsyncEventArgs e) { // skip if disposing -- not really needed, but nice for consistency if (_disposing) { return; } // determine which type of operation just completed and call the associated handler if (e.LastOperation == SocketAsyncOperation.Send) { // ensure not disposing _syncLock.TakeRead(); if (_disposing) { _syncLock.ReleaseRead(); return; } _syncLock.ReleaseRead(); try { // this send has completed are there more bytes to send? if (CompleteSend(e)) { // yes, send again StartSend(); } } catch (SocketException ex) { _sendLock.Release(); if (ex.SocketErrorCode == SocketError.ConnectionReset) { _syncLock.ReleaseRead(); return; } _syncLock.ReleaseRead(); ProcessError(ex); } catch (Exception ex) { _sendLock.Release(); _syncLock.ReleaseRead(); // handle error outside lock ProcessError(ex); } } else { if (_disposing) { return; } ProcessError("Unknown operation completed"); } }
/// <summary> /// This method is called when there is no more data to send to a connected client /// </summary> private void OnSocketSend(object sender, SocketAsyncEventArgs e) { // ensure not disposing _syncLock.TakeRead(); if (_disposing) { _syncLock.ReleaseRead(); return; } _syncLock.ReleaseRead(); try { // this send has completed are there more bytes to send? if (CompleteSend(e)) { // yes, send again StartSend(); } } catch (SocketException ex) { _sendLock.Release(); if (ex.SocketErrorCode == SocketError.ConnectionReset) { _syncLock.ReleaseRead(); return; } _syncLock.ReleaseRead(); ProcessError(ex); } catch (Exception ex) { _sendLock.Release(); _syncLock.ReleaseRead(); // handle error outside lock ProcessError(ex); } }