Switching to the UI thread should be done using JoinableTaskFactory.SwitchToMainThreadAsync
rather than legacy methods such as Dispatcher.Invoke or ThreadHelper.Invoke.
This avoids deadlocks and can reduce threadpool starvation.
void Foo() {
ThreadHelper.Generic.Invoke(delegate {
DoSomething();
});
}Use await SwitchToMainThreadAsync() instead, wrapping with JoinableTaskFactory.Run if necessary:
void Foo() {
ThreadHelper.JoinableTaskFactory.Run(async delegate {
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
DoSomething();
});
}In the above example, we obtain a JoinableTaskFactory instance from the ThreadHelper.JoinableTaskFactory static property
as it exists within Visual Studio itself. Other applications should create and expose their own JoinableTaskContext and/or JoinableTaskFactory for use in code that run in these applications.
See our doc on consuming JoinableTaskFactory from a library for more information.
This analyzer is configurable via the vs-threading.LegacyThreadSwitchingMembers.txt file.
See our configuration topic for more information.