private void Run(AsyncIOOperation ioOperation) { lock (_context._contextLock) { if (_stopped) { // Abort all operation after IO was stopped ioOperation.Complete(NativeMethods.ERROR_OPERATION_ABORTED, 0); return; } if (_runningOperation != null) { if (_nextOperation == null) { _nextOperation = ioOperation; // If there is an active read cancel it if (_runningOperation is AsyncReadOperation) { NativeMethods.HttpTryCancelIO(_handler); } } else { throw new InvalidOperationException("Only one queued operation is allowed"); } } else { // we are just starting operation so there would be no // continuation registered var completed = ioOperation.Invoke() != null; // operation went async if (!completed) { _runningOperation = ioOperation; } } } }
public void NotifyCompletion(int hr, int bytes) { AsyncIOOperation.AsyncContinuation continuation; AsyncIOOperation.AsyncContinuation?nextContinuation = null; lock (this) { Debug.Assert(_runningOperation != null); continuation = _runningOperation.Complete(hr, bytes); var next = _nextOperation; _nextOperation = null; _runningOperation = null; if (next != null) { if (_stopped) { // Abort next operation if IO is stopped nextContinuation = next.Complete(NativeMethods.ERROR_OPERATION_ABORTED, 0); } else { nextContinuation = next.Invoke(); // operation went async if (nextContinuation == null) { _runningOperation = next; } } } } continuation.Invoke(); nextContinuation?.Invoke(); }