Ejemplo n.º 1
0
        /// <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);
        }