示例#1
0
        protected override Task <decimal> InvokeTestMethodAsync(ExceptionAggregator aggregator)
        {
            SharedData.ExecutingTest(TestMethod);
            var sta  = StaTaskScheduler.DefaultSta;
            var task = Task.Factory.StartNew(async() =>
            {
                Debug.Assert(sta.StaThread == Thread.CurrentThread);

                using (await SharedData.TestSerializationGate.DisposableWaitAsync(CancellationToken.None))
                {
                    try
                    {
                        Debug.Assert(SynchronizationContext.Current is DispatcherSynchronizationContext);

                        // Reset our flag ensuring that part of this test actually needs WpfFact
                        s_wpfFactRequirementReason = null;

                        // Just call back into the normal xUnit dispatch process now that we are on an STA Thread with no synchronization context.
                        var invoker = new XunitTestInvoker(Test, MessageBus, TestClass, ConstructorArguments, TestMethod, TestMethodArguments, BeforeAfterAttributes, aggregator, CancellationTokenSource);
                        return(invoker.RunAsync().JoinUsingDispatcher(CancellationTokenSource.Token));
                    }
                    finally
                    {
                        // Cleanup the synchronization context even if the test is failing exceptionally
                        SynchronizationContext.SetSynchronizationContext(null);
                    }
                }
            }, CancellationTokenSource.Token, TaskCreationOptions.None, new SynchronizationContextTaskScheduler(sta.DispatcherSynchronizationContext));

            return(task.Unwrap());
        }
示例#2
0
        protected override Task <decimal> InvokeTestMethodAsync(ExceptionAggregator aggregator)
        {
            SharedData.ExecutingTest(TestMethod);
            Debug.Assert(StaTestFramework.IsCreated);

            var taskScheduler = new SynchronizationContextTaskScheduler(StaContext.Default.DispatcherSynchronizationContext);

            return(Task.Factory.StartNew(async() =>
            {
                Debug.Assert(SynchronizationContext.Current is DispatcherSynchronizationContext);

                using (await SharedData.TestSerializationGate.DisposableWaitAsync(CancellationToken.None))
                {
                    // Just call back into the normal xUnit dispatch process now that we are on an STA Thread with no synchronization context.
                    var invoker = new XunitTestInvoker(Test, MessageBus, TestClass, ConstructorArguments, TestMethod, TestMethodArguments, BeforeAfterAttributes, aggregator, CancellationTokenSource);
                    return await invoker.RunAsync();
                }
            }, CancellationTokenSource.Token, TaskCreationOptions.None, taskScheduler).Unwrap());
        }
        protected override Task <decimal> InvokeTestMethodAsync(ExceptionAggregator aggregator)
        {
            SharedData.ExecutingTest(TestMethod);

            DispatcherSynchronizationContext synchronizationContext = null;
            Dispatcher dispatcher = null;
            Thread     staThread;

            using (var staThreadStartedEvent = new ManualResetEventSlim(initialState: false))
            {
                staThread = new Thread((ThreadStart)(() =>
                {
                    // All WPF Tests need a DispatcherSynchronizationContext and we dont want to block pending keyboard
                    // or mouse input from the user. So use background priority which is a single level below user input.
                    synchronizationContext = new DispatcherSynchronizationContext();
                    dispatcher = Dispatcher.CurrentDispatcher;

                    // xUnit creates its own synchronization context and wraps any existing context so that messages are
                    // still pumped as necessary. So we are safe setting it here, where we are not safe setting it in test.
                    SynchronizationContext.SetSynchronizationContext(synchronizationContext);

                    staThreadStartedEvent.Set();

                    Dispatcher.Run();
                }));

                staThread.Name = $"{nameof(WpfTestRunner)} {TestMethod.Name}";
                staThread.SetApartmentState(ApartmentState.STA);
                staThread.Start();

                staThreadStartedEvent.Wait();
                Debug.Assert(synchronizationContext != null);
            }

            var taskScheduler = new SynchronizationContextTaskScheduler(synchronizationContext);
            var task          = Task.Factory.StartNew(async() =>
            {
                Debug.Assert(SynchronizationContext.Current is DispatcherSynchronizationContext);

                using (await SharedData.TestSerializationGate.DisposableWaitAsync(CancellationToken.None))
                {
                    // Sync up FTAO to the context that we are creating here.
                    ForegroundThreadAffinitizedObject.CurrentForegroundThreadData = new ForegroundThreadData(
                        Thread.CurrentThread,
                        new SynchronizationContextTaskScheduler(new DispatcherSynchronizationContext(Dispatcher.CurrentDispatcher, DispatcherPriority.Background)),
                        ForegroundThreadDataKind.StaUnitTest);

                    // Reset our flag ensuring that part of this test actually needs WpfFact
                    s_wpfFactRequirementReason = null;

                    // Just call back into the normal xUnit dispatch process now that we are on an STA Thread with no synchronization context.
                    var invoker = new XunitTestInvoker(Test, MessageBus, TestClass, ConstructorArguments, TestMethod, TestMethodArguments, BeforeAfterAttributes, aggregator, CancellationTokenSource);
                    return(await invoker.RunAsync());
                }
            }, CancellationTokenSource.Token, TaskCreationOptions.None, taskScheduler).Unwrap();

            return(Task.Run(
                       async() =>
            {
                try
                {
                    return await task.ConfigureAwait(false);
                }
                finally
                {
                    // Make sure to shut down the dispatcher. Certain framework types listed for the dispatcher
                    // shutdown to perform cleanup actions. In the absence of an explicit shutdown, these actions
                    // are delayed and run during AppDomain or process shutdown, where they can lead to crashes of
                    // the test process.
                    dispatcher.InvokeShutdown();

                    // Join the STA thread, which ensures shutdown is complete.
                    staThread.Join(HangMitigatingTimeout);
                }
            }));
        }