Dispatching a Method to the UI Thread

When you are building desktop or mobile user interfaces, parts of your code may execute on background threads. However, the user interface itself can be accessed only from the UI thread. Therefore, it is often necessary to dispatch execution of code from a background thread to the foreground thread.

Traditionally, thread dispatching has been implemented using the Invoke(Delegate) method in WinForms or the Dispatcher class in XAML. However, this results in a large amount of boilerplate, making the code unreadable.

The DispatchedAttribute aspect addresses the issue of thread dispatching by forcing a method to execute on the thread that created the object (typically the foreground thread).

This topic contains the following sections:

Forcing a method to execute on the foreground thread

Once you've added background processing to the button click, you will need a way to have the SaveCompleted method run on the UI thread. If you don't do this you will get an InvalidOperationException because setting the lblStatus.Text property is a cross threading operation.

Ui Threading Error

Here's how you can fix this:

  1. Your code has encapsulated the UI thread interaction in the SaveCompleted method. Open the smart tag on that method and choose to "execute the method in the object thread". This tells PostSharp to configure this method to execute in the thread that the class containing the method is executing in.

    Ui Object Thread Add
  2. After selecting the smart tag option you will be returned to your code and you'll notice that the only change was the addition of the [DispatchedAttribute] attribute to the SaveCompleted method.

    C#
    [Dispatched] 
    private void SaveCompleted() 
    { 
        lblStatus.Text = "Finished Saving"; 
    }
    Note Note

    Note, that [Dispatched] attribute can be applied only to instance methods of UI controls (WinForms or WPF), or to any class implementing the IDispatcherObject interface manually.

Now if you run your code you will no longer receive the InvalidOperationException and instead will see the label on the UI update. All of the Save functionality will occur in a separate thread which prevents the user interface from locking up while that is happening.

Executing a method asynchronously

By default, the DispatchedAttribute forces the target method to execute synchronously on the foreground thread, which means that the background thread will wait until the method execution has completed. This waiting causes some performance overhead. Additionally, synchronous execution is not always useful. If the method has no return value and no side effect of interest for the calling thread, the method could be safely executed asynchronously, which means the calling thread would not need to wait for the method execution to complete on the foreground thread, so that the calling thread would continue its execution immediately after having enqueued the call to the foreground thread.

You can enable asynchronous execution of a dispatched method by passing the true value to the parameter of the DispatchedAttribute(Boolean) constructor, for instance:

C#
[Dispatched(true)] 
private void SaveCompleted() 
{ 
    lblStatus.Text = "Finished Saving"; 
}
Executing async methods in the foreground thread

When you use the DispatchedAttribute aspect on asynchronous methods (async keyword in C#), the method is guaranteed to execute on the foreground thread even when it is invoked from a background thread.

See Also