public void BeforeTest(ITest test) { Assert.IsNull(ThreadHelper.JoinableTaskContext, "Tests with joinable tasks must not be run in parallel!"); IList apartmentState = null; for (var scope = test; scope is not null; scope = scope.Parent) { apartmentState = scope.Properties[nameof(ApartmentState)]; if (apartmentState.Count > 0) { break; } } if (!apartmentState.Contains(ApartmentState.STA)) { _denyExecutionSynchronizationContext = new DenyExecutionSynchronizationContext(SynchronizationContext.Current); ThreadHelper.JoinableTaskContext = new JoinableTaskContext(_denyExecutionSynchronizationContext.MainThread, _denyExecutionSynchronizationContext); return; } Assert.AreEqual(ApartmentState.STA, Thread.CurrentThread.GetApartmentState()); // This form is created to obtain a UI synchronization context only. using (new Form()) { // Store the shared JoinableTaskContext ThreadHelper.JoinableTaskContext = new JoinableTaskContext(); _hangReporter = new HangReporter(ThreadHelper.JoinableTaskContext); } }
private static (JoinableTaskContext joinableTaskContext, SynchronizationContext synchronizationContext) CreateJoinableTaskContext() { Thread mainThread; SynchronizationContext synchronizationContext; if (SynchronizationContext.Current is DispatcherSynchronizationContext) { // The current thread is the main thread, and provides a suitable synchronization context mainThread = Thread.CurrentThread; synchronizationContext = SynchronizationContext.Current; } else { // The current thread is not known to be the main thread; we have no way to know if the // synchronization context of the current thread will behave in a manner consistent with main thread // synchronization contexts, so we use DenyExecutionSynchronizationContext to track any attempted // use of it. var denyExecutionSynchronizationContext = new DenyExecutionSynchronizationContext( SynchronizationContext.Current ); mainThread = denyExecutionSynchronizationContext.MainThread; synchronizationContext = denyExecutionSynchronizationContext; } return( new JoinableTaskContext(mainThread, synchronizationContext), synchronizationContext ); }
public void BeforeTest(ITest test) { Application.ThreadException += HandleApplicationThreadException; IList apartmentState = null; for (var scope = test; scope != null; scope = scope.Parent) { apartmentState = scope.Properties[nameof(ApartmentState)]; if (apartmentState.Count > 0) { break; } } if (!apartmentState.Contains(ApartmentState.STA)) { _denyExecutionSynchronizationContext = new DenyExecutionSynchronizationContext(SynchronizationContext.Current); ThreadHelper.JoinableTaskContext = new JoinableTaskContext(_denyExecutionSynchronizationContext.MainThread, _denyExecutionSynchronizationContext); return; } Assert.AreEqual(ApartmentState.STA, Thread.CurrentThread.GetApartmentState()); // This form created for obtain UI synchronization context only using (new Form()) { // Store the shared JoinableTaskContext ThreadHelper.JoinableTaskContext = new JoinableTaskContext(); } }
internal static (JoinableTaskContext joinableTaskContext, SynchronizationContext synchronizationContext) CreateJoinableTaskContext() { Thread mainThread; SynchronizationContext synchronizationContext; switch (ForegroundThreadDataInfo.CreateDefault(ForegroundThreadDataKind.Unknown)) { case ForegroundThreadDataKind.JoinableTask: throw new NotSupportedException($"A {nameof(VisualStudio.Threading.JoinableTaskContext)} already exists, but we have no way to obtain it."); case ForegroundThreadDataKind.Wpf: case ForegroundThreadDataKind.WinForms: case ForegroundThreadDataKind.MonoDevelopGtk: case ForegroundThreadDataKind.MonoDevelopXwt: case ForegroundThreadDataKind.StaUnitTest: // The current thread is the main thread, and provides a suitable synchronization context mainThread = Thread.CurrentThread; synchronizationContext = SynchronizationContext.Current; break; case ForegroundThreadDataKind.ForcedByPackageInitialize: case ForegroundThreadDataKind.Unknown: default: // The current thread is not known to be the main thread; we have no way to know if the // synchronization context of the current thread will behave in a manner consistent with main thread // synchronization contexts, so we use DenyExecutionSynchronizationContext to track any attempted // use of it. var denyExecutionSynchronizationContext = new DenyExecutionSynchronizationContext(SynchronizationContext.Current); mainThread = denyExecutionSynchronizationContext.MainThread; synchronizationContext = denyExecutionSynchronizationContext; break; } return(new JoinableTaskContext(mainThread, synchronizationContext), synchronizationContext); }