/// <summary> /// Sends data asynchronously /// </summary> public void Write(RecyclableMemoryStream stream, Action onBufferFlush) { Interlocked.Exchange(ref _writeFlushCallback, onBufferFlush); if (_isClosing) { OnError(new SocketException((int)SocketError.Shutdown)); OnWriteFlushed(); return; } if (_sendSocketEvent != null) { _sendSocketEvent.BufferList = stream.GetBufferList(); var isWritePending = false; try { isWritePending = _socket.SendAsync(_sendSocketEvent); } catch (Exception ex) { OnError(ex); } if (!isWritePending) { OnSendCompleted(this, _sendSocketEvent); } } else { var length = (int)stream.Length; _socketStream.BeginWrite(stream.GetBuffer(), 0, length, OnSendStreamCallback, null); } }
/// <summary> /// Sends data asynchronously /// </summary> public void Write(RecyclableMemoryStream stream, Action onBufferFlush) { Interlocked.Exchange(ref _writeFlushCallback, onBufferFlush); if (_isClosing) { OnError(new SocketException((int)SocketError.Shutdown)); OnWriteFlushed(); return; } if (_sendSocketEvent != null) { _sendSocketEvent.BufferList = stream.GetBufferList(); var isWritePending = false; try { isWritePending = _socket.SendAsync(_sendSocketEvent); } catch (ObjectDisposedException) { OnError(null, SocketError.NotConnected); } catch (NullReferenceException) { // Mono can throw a NRE when being disposed concurrently // https://github.com/mono/mono/blob/b190f213a364a2793cc573e1bd9fae8be72296e4/mcs/class/System/System.Net.Sockets/SocketAsyncEventArgs.cs#L184-L185 // https://github.com/mono/mono/blob/b190f213a364a2793cc573e1bd9fae8be72296e4/mcs/class/System/System.Net.Sockets/Socket.cs#L2477-L2478 OnError(null, SocketError.NotConnected); } catch (Exception ex) { OnError(ex); } if (!isWritePending) { OnSendCompleted(this, _sendSocketEvent); } } else { var length = (int)stream.Length; try { _socketStream .WriteAsync(stream.GetBuffer(), 0, length) .ContinueWith(OnSendStreamCallback, TaskContinuationOptions.ExecuteSynchronously); } catch (Exception ex) { HandleStreamException(ex); } } }