/// <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);
         }
     }
 }