提交 a7c00b43 编写于 作者: J Jason Malinowski

Remove ForegroundThreadAffinitizedObject's dependency on WPF

ForegroundThreadAffinitizedObject took a WPF dependency so it could
create a lower-priority DispatcherSynchronizationContext, which
is something we can set up during our package load where we were
already forcing the foreground thread information to be initialized.
We also have to strengthen an assertion since we can't check for
application initialization anymore.
上级 192a2054
......@@ -4,8 +4,6 @@
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
using Microsoft.CodeAnalysis.Utilities;
using Roslyn.Utilities;
using static Microsoft.CodeAnalysis.Utilities.ForegroundThreadDataKind;
......@@ -34,12 +32,7 @@ internal static ForegroundThreadData CreateDefault(ForegroundThreadDataKind defa
{
var kind = ForegroundThreadDataInfo.CreateDefault(defaultKind);
// None of the work posted to the foregroundTaskScheduler should block pending keyboard/mouse input from the user.
// So instead of using the default priority which is above user input, we use Background priority which is 1 level
// below user input.
var taskScheduler = new SynchronizationContextTaskScheduler(new DispatcherSynchronizationContext(Dispatcher.CurrentDispatcher, DispatcherPriority.Background));
return new ForegroundThreadData(Thread.CurrentThread, taskScheduler, kind);
return new ForegroundThreadData(Thread.CurrentThread, new SynchronizationContextTaskScheduler(SynchronizationContext.Current), kind);
}
}
......@@ -86,17 +79,13 @@ public ForegroundThreadAffinitizedObject(bool assertIsForeground = false)
{
_foregroundThreadDataWhenCreated = CurrentForegroundThreadData;
// For sanity's sake, ensure that our idea of "foreground" is the same as WPF's. But we won't assert
// anything if we haven't figured it out yet.
Contract.ThrowIfFalse(
CurrentForegroundThreadData.Kind == ForegroundThreadDataKind.Unknown ||
Application.Current == null ||
Application.Current.Dispatcher.Thread == ForegroundThread);
// ForegroundThreadAffinitizedObject might not necessarily be created on a foreground thread.
// AssertIsForeground here only if the object must be created on a foreground thread.
if (assertIsForeground)
{
// Assert we have some kind of foreground thread
Contract.ThrowIfTrue(CurrentForegroundThreadData.Kind == ForegroundThreadDataKind.Unknown);
AssertIsForeground();
}
}
......
......@@ -46,6 +46,14 @@ public override Task<RunSummary> RunAsync(IMessageSink diagnosticMessageSink, IM
{
try
{
// 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.
var dispatcherSynchronizationContext = new DispatcherSynchronizationContext();
// 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(dispatcherSynchronizationContext);
// Sync up FTAO to the context that we are creating here.
ForegroundThreadAffinitizedObject.CurrentForegroundThreadData = new ForegroundThreadData(
Thread.CurrentThread,
......@@ -55,14 +63,6 @@ public override Task<RunSummary> RunAsync(IMessageSink diagnosticMessageSink, IM
// Reset our flag ensuring that part of this test actually needs WpfFact
s_wpfFactRequirementReason = null;
// 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.
var dispatcherSynchronizationContext = new DispatcherSynchronizationContext();
// 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(dispatcherSynchronizationContext);
// Just call back into the normal xUnit dispatch process now that we are on an STA Thread with no synchronization context.
var baseTask = base.RunAsync(diagnosticMessageSink, messageBus, constructorArguments, aggregator, cancellationTokenSource);
do
......
......@@ -2,7 +2,9 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Threading;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.Utilities;
using Microsoft.VisualStudio.Shell;
......@@ -17,10 +19,15 @@ protected override void Initialize()
{
base.Initialize();
// Assume that we are being initialized on the UI thread at this point.
var defaultForegroundThreadData = ForegroundThreadData.CreateDefault(
defaultKind: ForegroundThreadDataKind.ForcedByPackageInitialize);
ForegroundThreadAffinitizedObject.CurrentForegroundThreadData = defaultForegroundThreadData;
// Assume that we are being initialized on the UI thread at this point, and setup our foreground state
var kind = ForegroundThreadDataInfo.CreateDefault(ForegroundThreadDataKind.ForcedByPackageInitialize);
// None of the work posted to the foregroundTaskScheduler should block pending keyboard/mouse input from the user.
// So instead of using the default priority which is above user input, we use Background priority which is 1 level
// below user input.
var taskScheduler = new SynchronizationContextTaskScheduler(new DispatcherSynchronizationContext(Dispatcher.CurrentDispatcher, DispatcherPriority.Background));
ForegroundThreadAffinitizedObject.CurrentForegroundThreadData = new ForegroundThreadData(Thread.CurrentThread, taskScheduler, kind);
ForegroundObject = new ForegroundThreadAffinitizedObject();
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册