18

I'd like to design a class library and plan to use mutli-threading (i.e. BackgroundWorker). I will have to watch out for the thread context, from which updates are made for fields, if I plan to bind them to the GUI of the library consuming frontend. It's not a good idea to pass the reference of the GUI dispatcher to the library, as I read. But how can I get access to the dispatcher of the application that will use the library? Is this possible?

I tried Application.Current.Dispatcher and added a reference to WindowBase (as I didn't have the possibility to add System.Windows), but still can't resolve the dispatcher object.

rdoubleui
  • 3,554
  • 4
  • 30
  • 51

3 Answers3

28

The Application class is defined in PresentationFramework.dll. You need to reference that in order to be able to access the dispatcher through Application.Current.Dispatcher.

ite-klass
  • 44
  • 4
John Leidegren
  • 59,920
  • 20
  • 131
  • 152
  • 2
    I would agree that using SynchronizationContext is the way to go – aqwert May 31 '11 at 01:28
  • 1
    I would say that this does not meet my requirements. I cannot see yet how I can transfer this idea to the class library - maybe I'm missing something. – rdoubleui May 31 '11 at 19:29
  • 1
    Sorry about that, I misunderstood the question. I've changed my answer. – John Leidegren May 31 '11 at 20:18
  • 5
    Thanks, it answers my question. Besides `PresentationFramework` and `WindowBase` I also needed to reference `System.Xaml`. – rdoubleui May 31 '11 at 20:38
  • so where can I find this, I cant find it in my reference manager – Daan Luttik Aug 26 '14 at 18:53
  • @DaanLuttik are you targeting a client profile or older version of the framework? That's typically the reason why you don't find the assemblies. Otherwise they should definitely be browsable as everything mentioned here is part of the framework. – John Leidegren Aug 28 '14 at 09:06
8

I had same issue ie not being able to resolve Application.Current.Dispatcher and ended up passing the client gui dispatcher down to the library which just holds a Dispatcher ref (reference WindowsBase + using System.Windows.Threading).
I prefer this option that having my non GUI lib have to carry a ref to PresentationFramework.dll (which doesn't seem natural).
I guess its 6 of one, half a dozen of the other...

Ricibob
  • 7,505
  • 5
  • 46
  • 65
  • It's the way I've done it before, but it doesn't seem elegant to pass on the dispatcher reference down the object structure. I could be wrong. – rdoubleui May 30 '11 at 21:43
  • 1
    I didn't see an issue with adding a reference to PresentationFramework in class lib and calling Dispatcher. That way you don't need any extra properties|variables|constructor-variables|extra-comments and can just call Dispatcher.Invoke(...) :D (if it turns out i don't need Dispatcher.Invoke(...), remove PresentationFramework ref, done ezpz :p ) – FocusedWolf Apr 11 '18 at 21:27
3

If you make sure (such as with static members of a class) that you have a handy reference to the UI Dispatcher, you can do this:

public static void Run( Action a ) {
    if ( !_uiDispatcher.CheckAccess() ) {
        _uiDispatcher.BeginInvoke( a );
    }
    else {
        a();
    }
}

One or two MVVM frameworks I've looked at do stuff like this.

If you don't want to pass this Dispatcher reference down to the library, IoC containers are an option. You could also put this in a Common.dll for classes and interfaces that both the exe and class libraries need to reference. The exe can set up the correct reference, and the class library can call the Run() method.

Joel B Fant
  • 24,406
  • 4
  • 66
  • 67
  • 2
    I think the issue is actually getting the UI/main thread dispatcher while in library code – Ricibob May 30 '11 at 21:31
  • Similar problem, I could pass the `Dispatcher` reference to the class library and then use it in a `static` context from there on, if I'm getting you right? Then I could access it without passing it down to the nested objects?! – rdoubleui May 31 '11 at 19:34
  • 1
    Exactly, you keep it one place everything else can access. My mention of Common.dll would be if more than one library needs it, too, though there usually isn't reason to create a whole new library for it. It just needs to go in the one that everything else references to avoid circular dependencies. – Joel B Fant May 31 '11 at 19:41
  • This is an alternative approach, thank you. I marked John Leidegren's statement as the answer, as it answered my original question. – rdoubleui May 31 '11 at 20:40