private void ExitLockAndTryRunContinuations() { var c1 = _continuation; _continuation = null; _lock.Exit(); if (c1 is Action action) { ContinuationRunner.Run(action); } }
static void CallbackImpl(IAsyncResult ar) { var thiz = ar.AsyncState as BeginEndAwaiter; thiz._ar = ar; var r = Interlocked.Exchange(ref thiz._continuation, COMPLETED); if (r != null) { // continuation is registered before completed, run it now. ContinuationRunner.Run(r); } else { // completed before continuation registered. } }
public void OnCompleted(Action continuation) { var r = Interlocked.CompareExchange(ref _continuation, continuation, null); if (r == null) { // it havn't completed, continuation registered. } else if (r == COMPLETED) { // it have completed, run the continuation now. ContinuationRunner.Run(continuation); } else { throw new Exception("a continuation was already registered"); } }
public void UnsafeOnCompleted(Action continuation) { if (awaitable == COMPLETED) { ContinuationRunner.Run(continuation); } else if (awaitable is Task <T> task) { GetTaskAwaiter(task).UnsafeOnCompleted(continuation); } else if (awaitable is ReusableAwaiter <T> ra) { ra.UnsafeOnCompleted(continuation); } else if (awaitable is IAwaiter <T> ia) { ia.UnsafeOnCompleted(continuation); } else { throw WrongAwaitableType(); } }
/// <summary> /// Attempts to transition the exception state. /// </summary> /// <param name="result"></param> /// <returns></returns> public bool TrySetException(Exception exception) { bool lt = false; if (!this.IsCompleted) { _lock.Enter(ref lt); if (this.IsCompleted) { _lock.Exit(); return(false); } var c1 = _continuation; this._continuation = exception; this.state = State.Completed; _lock.Exit(); if (c1 is Action action) { ContinuationRunner.Run(action); } return(true); } return(false); }
private static void RunContinuation(Action c) { ContinuationRunner.Run(c); }