How to wait for background thread / operation to complete in WPF interface code?

eg. in Winforms I would write ...

// on UI Thread BackgroundWorker workerThread = new BackgroundWorker(); workerThread.DoWork += new DoWorkEventHandler(LoadChildren); workerThread.RunWorkerCompleted += new RunWorkerCompletedEventHandler(OnLoadChildrenCompleted); while (workerThread.IsBusy) { Application.DoEvents(); } 

In WPF, what is the equivalent of Application.DoEvents in Winforms?

I have a Child property in my ViewModel class. HierarchicalDataTemplate has been configured to read items from the Children property.
TreeView displays nodes. When a user extends node, children from node are generated from the results of this property

 public Node Children { get { // 1. time-consuming LINQ query to load children from a SQL DB // 2. return results } } 

So, I would like to run 1. in the background thread and wait for it to complete before returning the results ... maintaining the user interface.

Googling led me to this page, which uses DispatcherFrames to simulate the above method . But that seems to be too much work .. that alludes to "Am I doing it right?"

+4
source share
3 answers

As I understand it, you have a stream like this:

  • Do some preparatory work (UI thread)
  • Do some background work (other topics)
  • Do some finishing work (UI thread)

You want to wait for the second bullet to complete before you run the code in the third.

The easiest way to do this is to make the second bullet code code back into the user interface thread (in the usual way) to start the third bullet. If you really want to use local variables from a method, you can always use an anonymous method or a lambda expression to create a delegate to go to the background worker - but it would usually be easier to have only the "PostBackgroundWork" method or something like that.

EDIT: That would be nice for the property, as you pointed out in your edited question, but I would reorganize it as a request for children with a callback when it is complete. This avoids the entire mess of reentration and provides a clearer picture of what is actually happening.

+4
source

Calling DoEvents in a user interface thread in such a loop is not recommended in WinForms or WPF.

If your application cannot continue until this thread completes, then why is it in another thread?

If some parts of your application can continue, disable those bits that cannot and reuse them when the termination callback is called. Let the rest of the system handle its stuff. There is no need to loop with DoEvents, this is not a good practice.

Take a look at community content on MSDN .

This is a good article about DoEvents .

+1
source

In WPF, what is the equivalent of Application.DoEvents in Winforms?

There is no built-in, but you can easily write your own. Indeed, WPF gives you more messaging capabilities than Winforms. See my Dispatcher Frames blog post here . It includes an example showing how to mimic Application.DoEvents() .

+1
source

All Articles