public bool _RestartWith(CompletionLink next)
 {
     if (Interlocked.CompareExchange(ref this.next, next, null) != null)
     {
         return(false);
     }
     else
     {
         cancellationTokenSource.Cancel();
         try {
             task?.Wait();
         } catch (AggregateException aggregateException) {
             if (aggregateException.InnerExceptions.Count != 1 ||
                 !(aggregateException.InnerExceptions[0] is TaskCanceledException))
             {
                 throw;
             }
         }
         if (!isCompletedUninterrupted)
         {
             this.next     = next;
             next.previous = this;
         }
         return(true);
     }
 }
 public void StartNext(CompletionLink next) {
    var spinner = new SpinWait();
    while (!current._RestartWith(next)) {
       spinner.SpinOnce();
    }
    next._Start();
    current = next;
 }
        public void StartNext(CompletionLink next)
        {
            var spinner = new SpinWait();

            while (!current._RestartWith(next))
            {
                spinner.SpinOnce();
            }
            next._Start();
            current = next;
        }
 private void HandleCompletion()
 {
     previous?.HandleCompletion();
     completionHandlers.ForEach(x => x.Invoke());
     completionLatch.Set();
     if (this.previous != null)
     {
         this.previous.next = null;
         this.previous      = null;
     }
     this.completionHandlers.Clear();
 }
 public bool _RestartWith(CompletionLink next) {
    if (Interlocked.CompareExchange(ref this.next, next, null) != null) {
       return false;
    } else {
       cancellationTokenSource.Cancel();
       try {
          task?.Wait();
       } catch (AggregateException aggregateException) {
          if (aggregateException.InnerExceptions.Count != 1 ||
              !(aggregateException.InnerExceptions[0] is TaskCanceledException)) {
             throw;
          }
       }
       if (!isCompletedUninterrupted) {
          this.next = next;
          next.previous = this;
       }
       return true;
    }
 }
 public CompletionChain(Func <CancellationToken, bool> action)
 {
     this.action  = action;
     this.current = new CompletionLink(this, true, "_sentinel_link_", (cancellationToken) => true);
 }
 public CompletionChain(Func<CancellationToken, bool> action) {
    this.action = action;
    this.current = new CompletionLink(this, true, "_sentinel_link_", (cancellationToken) => true);
 }
 private void HandleCompletion() {
    previous?.HandleCompletion();
    completionHandlers.ForEach(x => x.Invoke());
    completionLatch.Set();
    if (this.previous != null) {
       this.previous.next = null;
       this.previous = null;
    }
    this.completionHandlers.Clear();
 }