✅ BackgroundWorker in WPF MVVM
Hi! I'm trying to get progressbar and text to update while performing a lengthy task. I was wondering if it is possible to do so or should I create a thread for "PerformTask" file separately? I tried to play around with BackgroundWorker, and it updates "CurrentProgress" variable, but UI updates only after execution. GitHub: https://github.com/EdgarKa/AsyncProgressDemo
Thank you 🙂
Edit: I dropped GitHub repo so it would be easier to see and/or run as due to files amount it would be lengthy
GitHub
GitHub - EdgarKa/AsyncProgressDemo
Contribute to EdgarKa/AsyncProgressDemo development by creating an account on GitHub.
8 Replies
BackgroundWorkers are a bit old, but they still work
it's a bit hard to unpack, so:
in your Method
InitializeBackgroundWorker()
you are setting the EventHandler DoWork
. This is actually the thing that will run when you do bw.RunWorkerAsync()
The Progress you report will need to be reported inside the DoWork
EventHandler. ProgressChanged
then runs on the UI thread, where you can update your UI as necessary. You can report Progress by calling ReportProgress
. Also, Cancellation needs to be handled in DoWork
, if you want to support it. You can check whether a BackgroundWorker was cancelled by just checking bw.CancellationPending
.
Once your BackgroundWorker completes, RunWorkerCompleted
is called. This will also run on the UI thread.
working example would be:
(cancellation would be implemented by checking bw.CancellationPending
in the while
loop for example)
Stephen Cleary made a good series of articles on backgroundworkers vs Tasks, you can check it out here https://blog.stephencleary.com/2013/05/taskrun-vs-backgroundworker-round-1.html
It explains the basics of both and compares themYeah, definitely use Task.Run
massively simpler
yes ofc, most of the stuff you do in WPF usually does not require even that, Task.Run is only really needed when you do CPU heavy stuff. Everything else is awaitable at least somewhere
so you can just use async Events or expand your Command class to support Async Commands and stuff
Thank you for your help @hengi! Issue is, it still makes UI change after "PerformTask" is executed. Is there a way to update UI between fist two "for loops" (for example move progress bar to 10) or it would require separating UI and command with thread?
oh yeah, you should not manipulate the background worker outside the Events
if you want to use the
PerformTask
class, you have to do it like this:
MainPageViewModel.cs
PerformTask.cs
ExecuteCommand.cs
BackgroundWorkers are just a bit old and they feel a bit like Java Threads? Where you subclass a Thread but with Events instead. Just treat the Events like enclosed actions, do not manipulate the BackgroundWorker outside of them except for CancellationThis is exactly what I needed! Thanks a lot! Didn't think it'd work on Thread.Sleep
I am also working with older version of .NET (where my main project is) so it might be as good to use BackgroundWorker. At the same time I'll be looking into Threads and Tasks
BackgroundWorkers take one ThreadPool Thread, Thread.Sleep sleeps the current Thread ^^
Was this issue resolved? If so, run
/close
- otherwise I will mark this as stale and this post will be archived until there is new activity.