Click here to Skip to main content
15,891,951 members
Articles / Desktop Programming / WPF
Tip/Trick

Update data to WPF control from another thread

Rate me:
Please Sign up or sign in to vote.
4.11/5 (5 votes)
10 Jul 2016CPOL2 min read 33K   539   4   5
Update WPF control from another thread apart from UI thread

Introduction

WPF is a powerful tool for developing desktop applications. While developing apps using WPF, many times a situation comes to update UI thread from another background thread or some other thread. This tip explains how to update WPF thread from another thread in a safe way.

Background

I hope you are at least aware of the basics of threading concepts. If not, then no worries. I wil explain here some of the basics.

"Thread is the mother of any process". Remember always, first thread comes and then it takes the shape of process. All threads won't become processes. However, each process must have thread. A process once come in live, i.e., when process is running in OS environment, then it has the capability to request for more OS threads just to delegate tasks and make its own life easy.

Now consider this process is WPF application running on OS. Each process has a thread associated with it, so does with WPF application which we call it as main thread, i.e., Dispatcher thread. All messaging, updating controls, commands, etc. will be taken care of through this main thread (Dispatcher thread). If we try to update any control apart from this main thread, WPF actively refuses and hence we get an exception saying, "This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread.".

There is access check making another thread fault for UI control update.

So what is the solution for this situation? It's simple, borrow UI thread context and update control through this context from any thread. Remember, we borrowed UI thread context so update will be done through UI thread only even call from another thread to do so.

Let's see first what is a problematic situation with example and then modify the code making the situation better.

Using the Code

Following is a sample code which updates listbox UI control from viewmodel in another thread apart from dispatcher thread:

C#
private void BeginWork()
{
    //time taking job
    //running in another thread
    Task.Factory.StartNew(() => 
    {
        IsWorkDone = false;
        var random = new Random();
        for (int number = 1; number < 100; number++ )
        {
            Numbers.Add(random.Next(100)); //This is where we get thread exception
            Thread.Sleep(1000);
        }
        IsWorkDone = true;
    });
}

Here, Numbers is an observable collection. This collection we want to update at runtime in another thread. As observable collection is binded to ListBox as collection source, we can't update data from another thread. To correct this problem, we will use UI's view context.

Using View Context

View context is nothing but thread synchronization context from main thread. This can be obtained from SynchronizationContext.Current under System.Threading. Following is the modified code using view context:

C#
private void BeginWork()
{
    Numbers.Clear();

    //time taking job
    //running in another thread
    Task.Factory.StartNew(() =>
    {
        IsWorkDone = false;
        var random = new Random();
        for (int number = 0; number < 5; number++)
        {
            ViewContext.Send(x => Numbers.Add
              (random.Next(100)), null); //now this is updating using main ui thread context
            Thread.Sleep(1000);
        }
        ViewContext.Send(x => { NumberSelected = Numbers[0]; IsWorkDone = true; }, null);
    });
}

In ViewModel, we keep a ViewContext property of type SynchronizationContext. In code behind, we assign value for this property like:

Quote:

((MainWindowViewModel)DataContext).ViewContext = SynchronizationContext.Current;

Points of Interest

This is the most simplest and safest way to update in UI thread context.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Lead Synerzip
India India
Passionate about .Net programming.
Having 10+years experience in .Net framework.
Loved working on WPF, WCF, Xamarin, MVVM, Prism
Web development using ASP, ASP.Net, MVC, Angular.JS, Knockout, JQuery, AJAX

Comments and Discussions

 
QuestionYou missed the boat... Pin
PureNsanity11-Jul-16 4:32
professionalPureNsanity11-Jul-16 4:32 
AnswerRe: You missed the boat... Pin
Jatin Jibhkate12-Jul-16 1:00
Jatin Jibhkate12-Jul-16 1:00 
GeneralRe: You missed the boat... Pin
PureNsanity12-Jul-16 7:37
professionalPureNsanity12-Jul-16 7:37 
QuestionEasier way Pin
EveryNameIsTakenEvenThisOne10-Jul-16 9:31
professionalEveryNameIsTakenEvenThisOne10-Jul-16 9:31 
.NET 4.5 has the following class/method
C#
BindingOperations.EnableCollectionSynchronization(Numbers,lockObject)


Now you can update the Collection from any thread without a problem.
AnswerRe: Easier way Pin
Jatin Jibhkate10-Jul-16 18:07
Jatin Jibhkate10-Jul-16 18:07 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.