Beispiel #1
0
        public void CanCancelMoveNext()
        {
            var xs = new CancellationTestAsyncEnumerable().Select(x => x).Where(x => true);

            var e   = xs.GetEnumerator();
            var cts = new CancellationTokenSource();
            var t   = e.MoveNext(cts.Token);

            cts.Cancel();

            try
            {
                t.Wait(WaitTimeoutMs);
                Assert.True(false);
            }
            catch
            {
                Assert.True(t.IsCanceled);
            }
        }
Beispiel #2
0
        public async Task CorrectCancel()
        {
            var disposed = new TaskCompletionSource <bool>();

            var xs = new CancellationTestAsyncEnumerable().WithDispose(() =>
            {
                disposed.TrySetResult(true);
            });

            var ys = xs.Select(x => x + 1).Where(x => true);

            var e   = ys.GetEnumerator();
            var cts = new CancellationTokenSource();
            var t   = e.MoveNext(cts.Token);

            cts.Cancel();

            try
            {
                t.Wait(WaitTimeoutMs);
            }
            catch
            {
                // Don't care about the outcome; we could have made it to element 1
                // but we could also have cancelled the MoveNext-calling task. Either
                // way, we want to wait for the task to be completed and check that
            }
            finally
            {
                // the cancellation bubbled all the way up to the source to dispose
                // it. This design is chosen because cancelling a MoveNext call leaves
                // the enumerator in an indeterminate state. Further interactions with
                // it should be forbidden.

                var result = await disposed.Task;
                Assert.True(result);
            }

            Assert.False(await e.MoveNext());
        }