/// <summary> /// It callbacks all operations already sent / or to be written, that do not have a response. /// Invoked from an IO Thread or a pool thread /// </summary> internal void CancelPending(Exception ex, SocketError?socketError = null) { _isCanceled = true; var wasClosed = Interlocked.Exchange(ref _writeState, Connection.WriteStateClosed) == Connection.WriteStateClosed; if (!wasClosed) { if (Closing != null) { Closing(this); } Connection.Logger.Info("Cancelling in Connection {0}, {1} pending operations and write queue {2}", Address, InFlight, _writeQueue.Count); if (socketError != null) { Connection.Logger.Verbose("The socket status received was {0}", socketError.Value); } } if (ex == null || ex is ObjectDisposedException) { if (socketError != null) { ex = new SocketException((int)socketError.Value); } else { //It is closing ex = new SocketException((int)SocketError.NotConnected); } } // Dequeue all the items in the write queue var ops = new LinkedList <OperationState>(); OperationState state; while (_writeQueue.TryDequeue(out state)) { ops.AddLast(state); } // Remove every pending operation while (!_pendingOperations.IsEmpty) { Interlocked.MemoryBarrier(); // Remove using a snapshot of the keys var keys = _pendingOperations.Keys.ToArray(); foreach (var key in keys) { if (_pendingOperations.TryRemove(key, out state)) { ops.AddLast(state); } } } Interlocked.MemoryBarrier(); OperationState.CallbackMultiple(ops, ex); Interlocked.Exchange(ref _inFlight, 0); }