Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF/Multithreading: UI Dispatcher in MVVM

So say in an MVVM environment, I'm in a background thread and I'd like to run an update on a ui control. So normally I'd go myButton.Dispatcher.BeginInvoke(blabla) but I don't have access to myButton (because the viewmodel doesn't have access to the view's controls). So what is the normal pattern for doing this?

(I guess there's always binding, but I'd like to know how to do it via the dispatcher)

like image 299
Shai UI Avatar asked Jan 07 '11 01:01

Shai UI


People also ask

When to use Dispatcher in WPF?

A dispatcher is often used to invoke calls on another thread. An example would be if you have a background thread working, and you need to update the UI thread, you would need a dispatcher to do it.

How Dispatcher works in WPF?

WPF Dispatcher is associated with the UI thread. The UI thread queues methods call inside the Dispatcher object. Whenever your changes the screen or any event executes, or call a method in the code-behind all this happen in the UI thread and UI thread queue the called method into the Dispatcher queue.

What is Dispatcher BeginInvoke?

BeginInvoke(DispatcherPriority, Delegate, Object) Executes the specified delegate asynchronously at the specified priority and with the specified argument on the thread the Dispatcher is associated with.

What does Dispatcher Invoke do?

Invoke(Action, DispatcherPriority, CancellationToken)Executes the specified Action synchronously at the specified priority on the thread the Dispatcher is associated with.


2 Answers

I usually use Application.Current.Dispatcher: since Application.Current is static, you don't need a reference to a control

like image 169
Thomas Levesque Avatar answered Oct 25 '22 16:10

Thomas Levesque


From Caliburn Micro source code :

public static class Execute
{
    private static Action<System.Action> executor = action => action();

    /// <summary>
    /// Initializes the framework using the current dispatcher.
    /// </summary>
    public static void InitializeWithDispatcher()
    {
#if SILVERLIGHT
        var dispatcher = Deployment.Current.Dispatcher;
#else
        var dispatcher = Dispatcher.CurrentDispatcher;
#endif
        executor = action =>{
            if(dispatcher.CheckAccess())
                action();
            else dispatcher.BeginInvoke(action);
        };
    }

    /// <summary>
    /// Executes the action on the UI thread.
    /// </summary>
    /// <param name="action">The action to execute.</param>
    public static void OnUIThread(this System.Action action)
    {
        executor(action);
    }
}

Before using it you'll have to call Execute.InitializeWithDispatcher() from the UI thread then you can use it like this Execute.OnUIThread(()=>SomeMethod())

like image 15
Catalin DICU Avatar answered Oct 25 '22 15:10

Catalin DICU