What Dispatcher should I use for UI operations in a Visual Studio 2010+ extension
Asked Answered
G

1

6

Currently I'm aware of the following Dispatcher objects.

  • If you have a text view, you can use IWpfTextView.VisualElement.Dispatcher.

  • If your class is constructed by MEF (marked with [Export] and not directly constructed from your own code), then you can use the fact that the MEF part resolution algorithm and construction occurs on the UI thread, allowing the use of Dispatcher.CurrentDispatcher. For example:

    [Export(typeof(ISomeInterface))]
    public class MyClass : ISomeInterface {
      private readonly Dispatcher _dispatcher;
    
      public MyClass() {
        _dispatcher = Dispatcher.CurrentDispatcher.
      }
    }
    
  • You can use Application.Current.Dispatcher from any code.

What, if any, is the recommended practice for obtaining a Dispatcher?

Gemmule answered 14/2, 2014 at 1:54 Comment(7)
The web editor takes your second approach (essentially) with WebEditor.DispatcherAllyn
Are you sure you need one? Why not capture SynchronizationContext.Current instead?Insectivorous
Do not rely on SynchronizationContext.Current being the UI thread sync context. A MEF part can be instantiated on any thread. The fact that most MEF parts are triggered into existence from packages (which do load on the UI thread) doesn't mean anything, it's just a coincidence.Pickett
@StephenCleary: How does that help? You still need to figure out where to capture it.Allyn
@SLaks: I encourage people (as much as possible) to depend on the context capture/resume of await first, then SynchronizationContext, with Dispatcher/ISynchronizeInvoke/CoreDispatcher last.Insectivorous
@StephenCleary There are cases in Visual Studio where certain non-UI operations must be executed on the UI thread. One example of this is IVsOutputWindow.CreatePane. Using a proper Dispatcher is one way to ensure this call is always executed on the correct thread, regardless of the manner in which the MEF part was instantiated. async/await are of little use when the operation doesn't start on the correct thread.Gemmule
@280Z28: Right. It's not always possible to avoid Dispatcher, and from Kirill's answer below it sounds like MEF is one of those cases. I just discourage its use in the general sense.Insectivorous
P
2

Do not take a dependency on MEF composing on UI thread. If it works for you right now, you're just getting lucky. Also MEF is delayed in nature and full of Lazy, so if you happen to realize it on a background thread, the entire subgraph will get realized on background.

I would use #1 or #3 (doesn't matter which, there is only one UI thread dispatcher, doesn't matter how you get to it).

Pickett answered 17/2, 2014 at 7:52 Comment(1)
Apparently, Microsoft.Internal.VisualStudio.PlatformUI.BackgroundDispatcher makes its own dispatchers on background threads.Allyn

© 2022 - 2024 — McMap. All rights reserved.