[PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283
        public static async Task BeginContext_handler_flows_into_new_thread()
        {
            var source  = new TaskCompletionSource <object?>();
            var watcher = new CallbackWatcher();

            var thread = new Thread(() =>
            {
                try
                {
                    using (watcher.ExpectCallback())
                        AmbientTasks.Add(Task.FromException(new Exception()));

                    source.SetResult(null);
                }
                catch (Exception ex)
                {
                    source.SetException(ex);
                }
            });

            AmbientTasks.BeginContext(ex => watcher.OnCallback());

            thread.Start();

            await source.Task;
        }
        [PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283
        public static async Task BeginContext_handler_flows_into_ThreadPool_QueueUserWorkItem()
        {
            var watcher = new CallbackWatcher();

            AmbientTasks.BeginContext(ex => watcher.OnCallback());

            var source = new TaskCompletionSource <object?>();

            ThreadPool.QueueUserWorkItem(_ =>
            {
                try
                {
                    using (watcher.ExpectCallback())
                        AmbientTasks.Add(Task.FromException(new Exception()));

                    source.SetResult(null);
                }
                catch (Exception ex)
                {
                    source.SetException(ex);
                }
            }, null);

            await source.Task;
        }
        [PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283
        public static void Handled_exceptions_do_not_appear_in_a_subsequent_call_to_WaitAllAsync()
        {
            AmbientTasks.BeginContext(handler => { });

            AmbientTasks.Add(Task.FromException(new Exception()));

            AmbientTasks.WaitAllAsync().Status.ShouldBe(TaskStatus.RanToCompletion);
        }
        [PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283
        public static void Exception_from_user_delegate_is_not_thrown_on_SynchronizationContext_when_there_is_a_BeginContext_handler([Values] PostOverload overload)
        {
            AmbientTasks.BeginContext(ex => { });

            using (SynchronizationContextAssert.ExpectSinglePost(postedAction => postedAction.Invoke()))
            {
                AmbientTasksPost(overload, () => throw new Exception());
            }
        }
        [PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283
        public static async Task BeginContext_handler_does_not_flow_from_inner_method_back_to_outer_method_after_await()
        {
            var watcher = new CallbackWatcher();

            AmbientTasks.BeginContext(ex => watcher.OnCallback());

            await InnerFunction();

            using (watcher.ExpectCallback())
                AmbientTasks.Add(Task.FromException(new Exception()));
        [PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283
        public static void Exception_from_user_delegate_is_not_in_task_from_next_call_to_WaitAllAsync_when_there_is_a_BeginContext_handler([Values] PostOverload overload)
        {
            AmbientTasks.BeginContext(ex => { });

            using (SynchronizationContextAssert.ExpectSinglePost(postedAction => postedAction.Invoke()))
            {
                AmbientTasksPost(overload, () => throw new Exception());
            }

            AmbientTasks.WaitAllAsync().Status.ShouldBe(TaskStatus.RanToCompletion);
        }
        [PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283
        public static void BeginContext_handler_is_replaced_with_next_call()
        {
            AmbientTasks.BeginContext(ex => Assert.Fail("This handler should not be called."));

            var watcher = new CallbackWatcher();

            AmbientTasks.BeginContext(ex => watcher.OnCallback());

            using (watcher.ExpectCallback())
                AmbientTasks.Add(Task.FromException(new Exception()));
        }
        [PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283
        public static void Exception_from_SynchronizationContext_post_before_invoking_delegate_is_not_handled_when_there_is_a_BeginContext_handler([Values] PostOverload overload)
        {
            AmbientTasks.BeginContext(ex => { });

            var exception = new Exception();

            using (SynchronizationContextAssert.ExpectSinglePost(postedAction => throw exception))
            {
                Should.Throw <Exception>(() => AmbientTasksPost(overload, () => { })).ShouldBeSameAs(exception);
            }
        }
        [PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283
        public static async Task BeginContext_handler_flows_across_await()
        {
            var watcher = new CallbackWatcher();

            AmbientTasks.BeginContext(ex => watcher.OnCallback());

            await Task.Yield();

            using (watcher.ExpectCallback())
                AmbientTasks.Add(Task.FromException(new Exception()));
        }
        [PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283
        public static async Task BeginContext_handler_flows_into_Task_Run()
        {
            var watcher = new CallbackWatcher();

            AmbientTasks.BeginContext(ex => watcher.OnCallback());

            await Task.Run(() =>
            {
                using (watcher.ExpectCallback())
                    AmbientTasks.Add(Task.FromException(new Exception()));
            });
        }
Beispiel #11
0
        [PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283
        public static void BeginContext_handler_receives_exception_thrown_from_func()
        {
            var exception = new Exception();
            var watcher   = new CallbackWatcher();

            AmbientTasks.BeginContext(ex =>
            {
                watcher.OnCallback();
                ex.ShouldBeSameAs(exception);
            });

            using (watcher.ExpectCallback())
                AmbientTasks.Add(() => throw exception);
        }
        [PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283
        public static void BeginContext_handler_receives_exceptions_from_synchronously_faulted_tasks()
        {
            var exception = new Exception();
            var watcher   = new CallbackWatcher();

            AmbientTasks.BeginContext(ex =>
            {
                watcher.OnCallback();
                ex.ShouldBeSameAs(exception);
            });

            using (watcher.ExpectCallback())
                AmbientTasks.Add(Task.FromException(exception));
        }
        [PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283
        public static void BeginContext_handler_can_be_removed()
        {
            AmbientTasks.BeginContext(ex => Assert.Fail("This handler should not be called."));

            AmbientTasks.BeginContext();

            var exception          = new Exception();
            var aggregateException = Should.Throw <AggregateException>(
                () => AmbientTasks.Add(Task.FromException(exception)));

            aggregateException.InnerExceptions.ShouldHaveSingleItem().ShouldBeSameAs(exception);

            AmbientTasks.WaitAllAsync().Status.ShouldBe(TaskStatus.Faulted);
        }
        [PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283
        public static void BeginContext_handler_is_not_executed_using_synchronization_context()
        {
            using (SynchronizationContextAssert.ExpectNoPost())
            {
                AmbientTasks.BeginContext(ex => { });

                AmbientTasks.Add(Task.FromException(new Exception()));

                using (Utils.WithTemporarySynchronizationContext(null))
                {
                    AmbientTasks.Add(Task.FromException(new Exception()));
                }
            }
        }
        [PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283
        public static void Exception_from_user_delegate_is_handled_by_BeginContext_handler([Values] PostOverload overload)
        {
            var exception = new Exception();
            var watcher   = new CallbackWatcher();

            AmbientTasks.BeginContext(ex =>
            {
                watcher.OnCallback();
                ex.ShouldBeSameAs(exception);
            });

            using (SynchronizationContextAssert.ExpectSinglePost(postedAction => postedAction.Invoke()))
            {
                using (watcher.ExpectCallback())
                    AmbientTasksPost(overload, () => throw exception);
            }
        }
        [PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283
        public static void BeginContext_handler_receives_exceptions_from_asynchronously_faulted_tasks()
        {
            var source    = new TaskCompletionSource <object?>();
            var exception = new Exception();
            var watcher   = new CallbackWatcher();

            AmbientTasks.BeginContext(ex =>
            {
                watcher.OnCallback();
                ex.ShouldBeSameAs(exception);
            });

            AmbientTasks.Add(source.Task);

            using (watcher.ExpectCallback())
                source.SetException(exception);
        }
        [PreventExecutionContextLeaks] // Workaround for https://github.com/nunit/nunit/issues/3283
        public static void Handled_exceptions_do_not_appear_in_task_returned_from_WaitAllAsync_while_waiting_for_task()
        {
            var source    = new TaskCompletionSource <object?>();
            var exception = new Exception();

            AmbientTasks.BeginContext(handler => { });

            AmbientTasks.Add(source.Task);

            var waitAllTask = AmbientTasks.WaitAllAsync();

            waitAllTask.IsCompleted.ShouldBeFalse();

            source.SetException(exception);

            waitAllTask.Status.ShouldBe(TaskStatus.RanToCompletion);
        }
            static async Task InnerFunction()
            {
                await Task.Yield();

                AmbientTasks.BeginContext(ex => Assert.Fail());
            }