Update UI Label when using Task.Factory.StartNew

2019-01-22 14:05发布

问题:

I am trying to make my UI more responsive in my WPF app. I spawn a new thread using

Task.Factory.StartNew( () => RecurseAndDeleteStart() );

In that method RecurseAndDeleteStart() I want to update a label in the UI with the file that is being deleted.

How does one accomplish this?

回答1:

Since it's WPF, you can use the Dispatcher and call Dispatcher.BeginInvoke to marshal the call back to the UI thread to update the label.

Alternatively, you can pass a TaskScheduler into your method, and use it to update the label as follows:

// This line needs to happen on the UI thread...
TaskScheduler uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();

Task.Factory.StartNew( () => RecurseAndDeleteStart(uiScheduler) );

Then, inside your method, when you want to update a label, you could do:

Task.Factory.StartNew( () => 
  {
      theLabel.Text = "Foo";
  }, CancellationToken.None, TaskCreationOptions.None, uiScheduler);

This will push the call back onto the UI thread's synchronization context.



回答2:

You have to use the label.Dispatcher.BeginInvoke(delegate) to invoke anything from a different thread that will change the contents of the label.