Пример #1
0
        public async Task CompletionSourceCompletesResultAsynchronously(bool runAsync)
        {
            var steps    = new Steps();
            var control  = new SemaphoreSlim(0);
            var control2 = new SemaphoreSlim(0);

            steps.Add("main.start");

            var options = runAsync ? TaskCreationOptions.RunContinuationsAsynchronously : TaskCreationOptions.None;
            var taskCompletionSource = new TaskCompletionSource <int>(options);
            var task = Task.Run(async() =>
            {
                steps.Add("task.start");

                // some delay to ensure we do not SetResult before awaiting the task completion source,
                // thus forcing the await on that task to actually await asynchronously
                //await control.WaitAsync().CfAwait();
                control.Wait();
                //await Task.Delay(2000).CfAwait();
                Thread.Sleep(2000);

                steps.Add("task.complete");
                taskCompletionSource.SetResult(42);
                steps.Add("task.continue");

                // keep running for a while - on the same thread!
                //await Task.Delay(200).CfAwait();
                Thread.Sleep(200);

                steps.Add("task.end");
            });

            steps.Add("main.wait");
            control.Release();
            await taskCompletionSource.Task.CfAwait();

            steps.Add("main.resume");

            // keep running for a while - on the same thread!
            //await Task.Delay(200).CfAwait();
            Thread.Sleep(200);

            steps.Add("main.continue");

            await Task.Yield();

            await task.CfAwait();

            steps.Add("main.end");

            Console.WriteLine(steps);

            // FIXME why does it *have* to be "not same thread"? this test can fail on some occasions
            // task.complete thread 18 == main.resume thread 18 -- for runAsync = true

            // task.complete and task.continue always run on same thread
            // task.complete and main.wait always run on different threads
            steps.AssertSameThread("task.complete", "task.continue");
            steps.AssertNotSameThread("task.complete", "main.wait");

            // task.complete and main.resume
            if (runAsync)
            {
                steps.AssertNotSameThread("task.complete", "main.resume"); // run on different threads
            }
            else
            {
                steps.AssertSameThread("task.complete", "main.resume"); // run on same thread
            }
            // FIXME if async, order here is not specified!
            //if (runAsync)
            //    steps.AssertOrder("task.continue", "main.resume"); // main.resume after task.continue since different thread
            //else
            if (!runAsync)
            {
                steps.AssertOrder("main.resume", "task.continue"); // main.resume before task.continue since same thread
            }
            steps.AssertOrder("main.resume", "main.end");
        }