public override bool ExecuteAsync(AsyncOperation operation, bool preferSync) { EnsureNonBlocking(); try { operation.CurrentAsyncContext = this; if (operation.IsReadNotWrite) { return(_readQueue.ExecuteAsync(operation, preferSync)); } else { return(_writeQueue.ExecuteAsync(operation, preferSync)); } } catch { operation.Next = null; CancellationRequestResult result = operation.RequestCancellationAsync(OperationCompletionFlags.CompletedCanceledSync); Debug.Assert(result == CancellationRequestResult.Cancelled); if (result == CancellationRequestResult.Cancelled) { operation.Complete(); } throw; } }
// Requests cancellation of a queued operation. // If the operation is not on the queue (because it already completed), NotFound is returned. // If the operation is not executing, it is removed from the queue and Cancelled is returned. // If the operation is executing, it stays on the queue, the operation gets marked as cancellation requested, // and Requested is returned. protected CancellationRequestResult RequestCancellationAsync(AsyncOperation operation, OperationCompletionFlags flags) { CancellationRequestResult result = CancellationRequestResult.NotFound; if (_tail == operation) // We're the last operation { result = operation.RequestCancellationAsync(flags); if (result == CancellationRequestResult.Cancelled) { if (operation.Next == operation) // We're the only operation. { _tail = null; } else { // Update tail do { _tail = _tail.Next; } while (_tail !.Next != operation); // Update head _tail.Next = operation.Next; } operation.Next = null; } } else if (_tail != null) // The list is multiple operations and we're not the last { ref AsyncOperation nextOperation = ref _tail.Next !; do { if (nextOperation == operation) { result = operation.RequestCancellationAsync(flags); if (result == CancellationRequestResult.Cancelled) { nextOperation = operation.Next !; operation.Next = null; } break; } nextOperation = ref nextOperation.Next !; } while (nextOperation != _tail); }