Пример #1
0
 public static Task Run <T>(
     this AsyncCoroutineProxy <T> @this,
     IAsyncApartment apartment,
     Func <CancellationToken, IAsyncEnumerable <T> > routine,
     CancellationToken token)
 {
     return(apartment.Run(
                () => @this.Run(routine, token),
                token));
 }
        public async Task test_two_coroutines_execution_flow()
        {
            // Here we execute two cotoutines, CoroutineA and CoroutineB,
            // which asynchronously yield to each other

            //TODO: test cancellation scenarios
            var token = CancellationToken.None;

            // use ThreadPoolApartment to impose asynchronous continuations for all awaits,
            // regardless if the task has completed synchronously
            // the reasoning behind this is essentially the same as for
            // the TaskContinuationOptions.RunContinuationsAsynchronously option:
            // https://tinyurl.com/RunContinuationsAsynchronously

            await using var apartment = new Tests.ThreadPoolApartment();
            await apartment.Run(async() =>
            {
                var proxyA = new AsyncCoroutineProxy <string>();
                var proxyB = new AsyncCoroutineProxy <string>();

                var listener = new Tests.CategoryTraceListener(TRACE_CATEGORY);
                Trace.Listeners.Add(listener);
                try
                {
                    // start both coroutines
                    await Task.WhenAll(
                        proxyA.Run(token => CoroutineA(proxyB, token), token),
                        proxyB.Run(token => CoroutineB(proxyA, token), token))
                    .WithAggregatedExceptions();
                }
                finally
                {
                    Trace.Listeners.Remove(listener);
                }

                var traces = listener.ToArray();
                Assert.AreEqual(traces[0], "A about to yeild: 1");
                Assert.AreEqual(traces[1], "B received: 1 from A");
                Assert.AreEqual(traces[2], "B about to yeild: 1");
                Assert.AreEqual(traces[3], "A received: 1 from B");
                Assert.AreEqual(traces[4], "A about to yeild: 2");
                Assert.AreEqual(traces[5], "B received: 2 from A");
                Assert.AreEqual(traces[6], "B about to yeild: 2");
                Assert.AreEqual(traces[7], "A received: 2 from B");
                Assert.AreEqual(traces[8], "A about to yeild: 3");
                Assert.AreEqual(traces[9], "B received: 3 from A");
            });
        }