internal void Register(AsyncContextOperation operation) { CheckDisposed(); CheckCurrent(); ImmutableHashSet <AsyncContextOperation> capture, updated; do { capture = _operations; updated = capture.Add(operation); if (capture.Count == updated.Count) { return; // operation is already present } if (_state != State.Active) // The closest to the effective add in order to reduce the risk to need a rollback { throw new InvalidOperationException("The AsyncContext is already completing, you cannot register more tasks."); } } while (Interlocked.CompareExchange(ref _operations, updated, capture) != capture); // The state was updated while we where adding the operation ... rollback and throw! if (_state != State.Active) { UnRegisterCore(operation); throw new InvalidOperationException("The AsyncContext is already completing, you cannot register more tasks."); } UpdateState(); }
public void Register(Task task) { CheckDisposed(); CheckCurrent(); AsyncContextOperation.FromTask(task); // Will register itself on this context (as it's the Current) }
internal void UnRegisterCore(AsyncContextOperation operation) { ImmutableHashSet <AsyncContextOperation> capture, updated; do { capture = _operations; updated = capture.Remove(operation); if (capture.Count == updated.Count) { return; } } while (Interlocked.CompareExchange(ref _operations, updated, capture) != capture); }
internal void UnRegister(AsyncContextOperation operation) { UnRegisterCore(operation); UpdateState(); }