public void SetFromCompletedTaskVoid() {
        var cex = new Exception[] { new InvalidEnumArgumentException(), new InvalidProgramException() };

        var r1 = new TaskCompletionSource();
        r1.SetFromCompletedTask(Tasks.RanToCompletion());
        r1.Task.AssertRanToCompletion();

        var r2 = new TaskCompletionSource();
        r2.SetFromCompletedTask(Tasks.Cancelled());
        r2.Task.AssertCancelled();

        var r3 = new TaskCompletionSource();
        r3.SetFromCompletedTask(Tasks.Faulted(new InvalidEnumArgumentException()));
        r3.Task.AssertFailed<InvalidEnumArgumentException>();

        var r4 = new TaskCompletionSource();
        r4.SetFromCompletedTask(Tasks.Faulted(cex));
        r4.Task.AssertFailed<AggregateException>().InnerExceptions.AssertSequenceEquals(cex);

        // failed transitions
        Util.ExpectException<InvalidOperationException>(() => r1.SetFromCompletedTask(Tasks.RanToCompletion()));
        Util.ExpectException<InvalidOperationException>(() => r1.SetFromCompletedTask(Tasks.Cancelled()));
        Util.ExpectException<InvalidOperationException>(() => r1.SetFromCompletedTask(Tasks.Faulted(new InvalidEnumArgumentException())));
        Util.ExpectException<InvalidOperationException>(() => r1.SetFromCompletedTask(Tasks.Faulted(cex)));
    }
 public void WorksWithReentrancy() {
     for (var i = 0; i < 25; i++) {
         var r = new DiscardRedundantWorkThrottle();
         var h = new TaskCompletionSource();
         Task t = null;
         r.SetNextToAction(() => t = r.SetNextToAsyncFunction(() => h.Task)).AssertRanToCompletion();
         t.AssertNotCompleted(timeout: TimeSpan.FromMilliseconds(5));
         h.SetRanToCompletion();
         t.AssertRanToCompletion();
     }
 }
 public void NoOverlap() {
     var r = new ExclusiveSynchronizationContext();
     var n = 0;
     for (var i = 0; i < 1000; i++) {
         r.Post(z => {
             Assert.IsTrue(Interlocked.Increment(ref n) == 1);
             Assert.IsTrue(Interlocked.Decrement(ref n) == 0);
         }, null);
     }
     var a = new TaskCompletionSource();
     r.Post(z => a.SetRanToCompletion(), null);
     a.Task.AssertRanToCompletion();
 }
 public void WaitsForAsyncAndCancels() {
     var r = new DiscardRedundantWorkThrottle();
     var h = new TaskCompletionSource();
     
     var t1 = r.SetNextToAsyncFunction(() => h.Task);
     var t2 = r.SetNextToAction(() => { });
     new[] { t1, t2 }.WhenAny().AssertNotCompleted();
     
     var t3 = r.SetNextToAction(() => { });
     t2.AssertCancelled();
     new[] {t1, t3}.WhenAny().AssertNotCompleted();
     
     h.SetRanToCompletion();
     t1.AssertRanToCompletion();
     t3.AssertRanToCompletion();
 }
 public void NoInterference() {
     var r = new ExclusiveSynchronizationContext();
     var n = 0;
     var t = Task.WhenAll(Enumerable.Range(0, 5).Select(async e => await Task.Factory.StartNew(() => {
         for (var i = 0; i < 500; i++) {
             r.Post(z => {
                 n += 1;
             }, null);
         }
         var a = new TaskCompletionSource();
         r.Post(z => a.SetRanToCompletion(), null);
         a.Task.AssertRanToCompletion();
     })));
     t.AssertRanToCompletion(timeout: TimeSpan.FromSeconds(20)); // lots of work, long timeout
     Assert.IsTrue(n == 500 * 5);
 }
    public void TaskToAwaitConversionCompletion() {
        var r = new TaskCompletionSource<int>();
        var rt = r.Task.AsIAwaitable().AsTask();
        var rv = ((Task)r.Task).AsIAwaitable().AsTask();
        
        Task.WhenAny(rv, rt).AssertNotCompleted();
        r.SetResult(1);

        // worked before
        rt.AssertRanToCompletion().AssertEquals(1);
        rv.AssertRanToCompletion();

        // works after
        r.Task.AsIAwaitable().AsTask().AssertRanToCompletion().AssertEquals(1);
        ((Task)r.Task).AsIAwaitable().AsTask().AssertRanToCompletion();
    }
    public void TaskToAwaitConversionCancel() {
        var r = new TaskCompletionSource<int>();
        var rt = r.Task.AsIAwaitable().AsTask();
        var rv = ((Task)r.Task).AsIAwaitable().AsTask();

        Task.WhenAny(rv, rt).AssertNotCompleted();
        r.SetCanceled();

        // worked before
        rt.AssertCancelled();
        rv.AssertCancelled();

        // works after
        r.Task.AsIAwaitable().AsTask().AssertCancelled();
        ((Task)r.Task).AsIAwaitable().AsTask().AssertCancelled();
    }
    public void TaskToAwaitConversionFault() {
        var r = new TaskCompletionSource<int>();
        var rt = r.Task.AsIAwaitable().AsTask();
        var rv = ((Task)r.Task).AsIAwaitable().AsTask();

        Task.WhenAny(rv, rt).AssertNotCompleted();
        var ex = new InvalidOperationException();
        r.SetException(ex);

        // worked before
        rt.AssertFailed<InvalidOperationException>().AssertEquals(ex);
        rv.AssertFailed<InvalidOperationException>().AssertEquals(ex);

        // works after
        r.Task.AsIAwaitable().AsTask().AssertFailed<InvalidOperationException>().AssertEquals(ex);
        ((Task)r.Task).AsIAwaitable().AsTask().AssertFailed<InvalidOperationException>().AssertEquals(ex);
    }
    public void SourceTransitions() {
        new TaskCompletionSource().Task.AssertNotCompleted();
        var cex = new Exception[] { new InvalidEnumArgumentException(), new InvalidProgramException() };

        var r1 = new TaskCompletionSource();
        r1.SetRanToCompletion();
        r1.Task.AssertRanToCompletion();

        var r2 = new TaskCompletionSource();
        r2.TrySetRanToCompletion().AssertIsTrue();
        r2.Task.AssertRanToCompletion();

        var r3 = new TaskCompletionSource();
        r3.SetCanceled();
        r3.Task.AssertCancelled();

        var r4 = new TaskCompletionSource();
        r4.TrySetCanceled().AssertIsTrue();
        r4.Task.AssertCancelled();

        var r5 = new TaskCompletionSource();
        r5.SetException(new InvalidEnumArgumentException());
        r5.Task.AssertFailed<InvalidEnumArgumentException>();

        var r6 = new TaskCompletionSource();
        r6.SetException(cex);
        r6.Task.AssertFailed<AggregateException>().InnerExceptions.AssertSequenceEquals(cex);

        var r7 = new TaskCompletionSource();
        r7.TrySetException(new InvalidEnumArgumentException()).AssertIsTrue();
        r7.Task.AssertFailed<InvalidEnumArgumentException>();

        // failed transitions
        Util.ExpectException<InvalidOperationException>(r1.SetRanToCompletion);
        Util.ExpectException<InvalidOperationException>(r1.SetCanceled);
        Util.ExpectException<InvalidOperationException>(() => r1.SetException(new Exception()));
        Util.ExpectException<InvalidOperationException>(() => r1.SetException(cex));
        r1.TrySetRanToCompletion().AssertIsFalse();
        r1.TrySetCanceled().AssertIsFalse();
        r1.TrySetException(new Exception()).AssertIsFalse();
        r1.TrySetException(cex).AssertIsFalse();
    }
    public void TrySetFromCompletedTaskGeneric() {
        var cex = new Exception[] { new InvalidEnumArgumentException(), new InvalidProgramException() };

        var r1 = new TaskCompletionSource<int>();
        r1.TrySetFromCompletedTask(Tasks.RanToCompletion(1)).AssertIsTrue();
        r1.Task.AssertRanToCompletion();

        var r2 = new TaskCompletionSource<int>();
        r2.TrySetFromCompletedTask(Tasks.Cancelled<int>()).AssertIsTrue();
        r2.Task.AssertCancelled();

        var r3 = new TaskCompletionSource<int>();
        r3.TrySetFromCompletedTask(Tasks.Faulted<int>(new InvalidEnumArgumentException())).AssertIsTrue();
        r3.Task.AssertFailed<InvalidEnumArgumentException>();

        var r4 = new TaskCompletionSource<int>();
        r4.TrySetFromCompletedTask(Tasks.Faulted<int>(cex)).AssertIsTrue();
        r4.Task.AssertFailed<AggregateException>().InnerExceptions.AssertSequenceEquals(cex);

        // failed transitions
        r1.TrySetFromCompletedTask(Tasks.RanToCompletion(1)).AssertIsFalse();
        r1.TrySetFromCompletedTask(Tasks.Cancelled<int>()).AssertIsFalse();
        r1.TrySetFromCompletedTask(Tasks.Faulted<int>(new InvalidEnumArgumentException())).AssertIsFalse();
        r1.TrySetFromCompletedTask(Tasks.Faulted<int>(cex)).AssertIsFalse();
    }
    public void EventuallyTrySetFromTaskGeneric() {
        var r1 = new TaskCompletionSource<int>();
        var r2 = new TaskCompletionSource<int>();
        var t3 = r1.EventuallyTrySetFromTask(r2.Task);
        r1.Task.AssertNotCompleted();
        t3.AssertNotCompleted();

        r2.TrySetResult(1);
        t3.AssertRanToCompletion().AssertIsTrue();
        r1.Task.AssertRanToCompletion().AssertEquals(1);

        r1.EventuallyTrySetFromTask(r2.Task).AssertRanToCompletion().AssertIsFalse();
    }
    public void EventuallyTrySetFromTaskVoid() {
        var r1 = new TaskCompletionSource();
        var r2 = new TaskCompletionSource();
        var t3 = r1.EventuallyTrySetFromTask(r2.Task);
        r1.Task.AssertNotCompleted();
        t3.AssertNotCompleted();

        r2.TrySetRanToCompletion();
        t3.AssertRanToCompletion().AssertIsTrue();
        r1.Task.AssertRanToCompletion();

        r1.EventuallyTrySetFromTask(r2.Task).AssertRanToCompletion().AssertIsFalse();
    }
    public void EventuallySetFromTaskGeneric() {
        var r1 = new TaskCompletionSource<int>();
        var r2 = new TaskCompletionSource<int>();
        var t3 = r1.EventuallySetFromTask(r2.Task);
        r1.Task.AssertNotCompleted();
        t3.AssertNotCompleted();

        r2.SetResult(1);
        t3.AssertRanToCompletion();
        r1.Task.AssertRanToCompletion().AssertEquals(1);
        
        r1.EventuallySetFromTask(r2.Task).AssertFailed<InvalidOperationException>();
    }
    public void EventuallySetFromTaskVoid() {
        var r1 = new TaskCompletionSource();
        var r2 = new TaskCompletionSource();
        var t3 = r1.EventuallySetFromTask(r2.Task);
        r1.Task.AssertNotCompleted();
        t3.AssertNotCompleted();

        r2.SetRanToCompletion();
        t3.AssertRanToCompletion();
        r1.Task.AssertRanToCompletion();

        r1.EventuallySetFromTask(r2.Task).AssertFailed<InvalidOperationException>();
    }