0

I have code (method/function) that retrieves data from a server and builds XAML. The code goes through a loop so the fetching of data is mixed with the code that creates the UI elements.

I want the main thread to stay responsive. I know I can't update the UI in "DoWork" without using a Dispatcher, but there is a lot of XAML code. Can I somehow wrap the whole method using Dispatacher and Delegate? What is the best approach to achieve this?

EDIT/UPDATE I ended up managing to separate the fetching of data from the XAML code. I just had to create a few more classes to temporarily hold the data. Thanks to all for your comments and suggestions.

Ross Kelly
  • 477
  • 1
  • 6
  • 23
  • Possible duplicate of [Change WPF controls from a non-main thread using Dispatcher.Invoke](https://stackoverflow.com/questions/1644079/change-wpf-controls-from-a-non-main-thread-using-dispatcher-invoke) – Peter Duniho Oct 05 '19 at 01:18
  • Possible duplicate of [How to update UI from another thread running in another class](https://stackoverflow.com/questions/9602567/how-to-update-ui-from-another-thread-running-in-another-class) – Peter Duniho Oct 05 '19 at 01:19
  • Possible duplicate of [How to update GUI with backgroundworker?](https://stackoverflow.com/questions/1862590/how-to-update-gui-with-backgroundworker) – Peter Duniho Oct 05 '19 at 01:19
  • 1
    For posterity, if when the above comments are deleted automatically (i.e. when the question is closed as a duplicate): several duplicates, including https://stackoverflow.com/questions/1644079/change-wpf-controls-from-a-non-main-thread-using-dispatcher-invoke, https://stackoverflow.com/questions/9602567/how-to-update-ui-from-another-thread-running-in-another-class, and https://stackoverflow.com/questions/1862590/how-to-update-gui-with-backgroundworker – Peter Duniho Oct 05 '19 at 01:20
  • 2
    I will note that none of these have what I think is really the best _general_ answer: do nothing. If you are using MVVM to start with, i.e. all UI updates are done implicitly by updating view model properties, then WPF already handles the cross-thread aspect on your behalf, marshaling the property update change to the UI thread as necessary. You definitely don't want to just wrap all your background worker method in a call to `Dispatcher.Invoke()`, because then you're just putting all the work back on the UI thread, rendering the background thread pointless. – Peter Duniho Oct 05 '19 at 01:22

1 Answers1

-2

Converting your code to use MVVM and binding to properties and commands as suggested will be the best solution in the end.

In the meantime, you could break up the processing parts into chunks and update the UI in between.

For I/O operations the functions for retrieving them are probably already async so you can await them. For CPU operations, you can wrap in Task.Run()

e.g.

public async Task ProcessData(...) {        
    for (DataSource source in DataSourceURIs) {
        Data data = await FetchDataAsync(source);
        //Update UI here
        ProcessedData processedData = await Task.Run(() => SomeCPUOperation(data));
        //Update UI herea
     }
}

https://www.pluralsight.com/guides/using-task-run-async-await

geometrikal
  • 3,195
  • 2
  • 29
  • 40