Acquiring, casting, or invoking single-threaded objects should be done after ensuring that your code is running on the main thread.
This analyzer can be configured to:
- Recognize the objects that are single-threaded that are unique to your app or library.
- Recognize synchronous methods that verify the caller is already on the main thread.
- Recognize methods that switch to the main thread when the caller awaits them.
Calls to
JoinableTaskFactory.SwitchToMainThreadAsync
methods are pre-configured.
See our configuration topic to learn more about customizing this analyzer.
This analyzer also recognizes requirements to use the main thread transitively within your solution.
For example, if method A()
invokes a type that we know from configuration requires the main thread,
and B()
calls A()
, then the B
method also needs the UI thread transitively.
This analyzer flags B()
as needing to call a method that throws if not already on the main thread
only when A()
is written to call such a method.
NOTE: This analyzer requires full solution analysis.
This example is based on the configuration available from the Visual Studio SDK
that defines IVs*
interfaces as requiring the main thread.
private void CallVS()
{
IVsSolution sln = GetIVsSolution();
sln.SetProperty(); // This analyzer will report warning on this invocation.
}
First ensure you are running on the main thread before interacting with single-threaded objects. Either throw when you are not on the appropriate thread, or explicitly switch to the main thread.
This solution example is based on the configuration available from the Visual Studio SDK
that defines ThreadHelper.ThrowIfNotOnUIThread()
as one which throws if the caller
is not already on the main thread.
private void CallVS()
{
ThreadHelper.ThrowIfNotOnUIThread();
IVsSolution sln = GetIVsSolution();
sln.SetProperty(); // This analyzer will not report warning on this invocation.
}
private async Task CallVSAsync()
{
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
IVsSolution sln = GetIVsSolution();
sln.SetProperty(); // This analyzer will not report warning on this invocation.
}
Refer to Asynchronous and multithreaded programming within VS using the JoinableTaskFactory for more info.