BrandGhost

EASY Asynchronous Progress Bar Updates in WPF and C#

In the history of progress bars there has NEVER been one that was remotely close to accurate. BUT that shouldn't stop you from adding your own into your WPF application! In this video tutorial, I'll walk you through how we can get asynchronous progress working for a progress bar control in WPF. We'll build on the previous splash screen example and solve more cross-thread issues! Remember... YOU could be the one to change the course of progress bars FOREVER! Make yours report accurate progress. Do it for all of us.
View Transcript
something that's plagg every single one of us as a user are progress bars in this video I'm not going to give you a solution to progress bars but we're going to see how we can go make them work on a splash screen hi my name is Nick centino and I'm a principal software engineering manager at Microsoft in a previous video which I'll link up here if you haven't seen yet we were creating a Splash Window inside of WPF and I promise you that if you stayed to the end of that video that we could see how we could get progress bars to go work in that video I had an indeterminate progress bar it just kind of shows that are moving along that way you know your user interface isn't totally frozen but it's not really that helpful to users so in this video we're going to walk through how you can use some interfaces and some method calls to make sure that we can get progress set up for our splash screen if that sounds interesting remember to subscribe to the channel and check out that pin comment for my courses on dome train with that said let's go see some progress all right on my screen I have the aaml preview in Visual Studio here this is our beautiful splash screen okay it's actually pretty terrible it's really ugly you probably want to put a nice beautiful picture here I don't have that so you get magenta instead but you can see that the progress bar is just kind of scrolling along this is the indeterminate mode for a progress bar but we're going to make some changes here to ensure that we can go set it what I'm going to do is scroll down a little bit lower in the zaml here to our progress bar I'm going to take off the is indeterminant property here we'll get rid of that and now it's just a normal boring progress bar so we need to do something with this progress bar to go update it in order to make that happen I'm going to walk through a little bit of our splash screen logic that we had from the previous video like I said you're going to want to go watch that first and come back to this one if you have not yet seen that but in that we were looking at a splash presenter which would put the splash screen up for us and a little bit lower we had this opportunity where we could go run some background work when you're running background work that's probably the spot that you're going to want to be able to say hey look I know I've made progress right I have to go load some files I have to go connect to some Services I have to go restore some State whatever your applications doing at startup that's the spot where you're going to know about the progress you're making so we need a way to be able to tell that bit of code hey look if you want to be able to inform us about any progress use this thing whatever that is which we'll see in a moment but use this thing and that way if you want to tell us about the progress youve made no problem call it use it and that way we can show the progress for you this is just a brief Interruption to remind you that I do have courses available on dome train focused on C so whether you're interested in getting started in C looking for a little bit more of an intermediate course focus on object-oriented programming and some async programming or are you just looking to update your refactoring skills and see some examples that we can walk through together you can go ahead and check them out by visiting the links in the description and the comment below thanks and back to the video video we have to have something that we can provide into here in order to get progress so what I'm going to do is I'm going to change our API here it this should say splash screen progress and you'll notice that this is the old parameter that we passed in I'm going to get rid of it in just a moment I'll comment it out for now I progress is a builtin interface that we can use that's meant for this sort of thing it's pretty lightweight if I jump over to it you can see that it just has a report method and it's a type parameter so it's not just an integer or a floating Point number you can use anything you want to report progress on but it's really simple just this one method it's up for us to figure out how we want to go Implement that in my case here I'm going to use splash screen progress as the state that we're using and that way we can have that passed in and have it available for the person who is doing the work in the background and they can call the report method on this thing to have any status updates so if we go back up here I'm going to go add this back in I was hiding it in plain sight so we have splash screen progress now this compiles I can get rid of that and if we jump back up to our background work that we're doing this dohey work async call back no longer is compatible and that's because it needs two parameters passed in so this would be progress and then the cancellation token which means now we do have access to progress right so if I type here I can go report progress and then I need to give it a splash screen progress instance that we go make fortunately for us I've gone ahead and done that ahead of time this is going to be very simple but you'll see here that I have this progress info I've actually changed this from a previous video so I'm going to go put this back let's go do this this should basically get us the percentage along the way so it's going to go up by 2% every time and then it's also going to have a message because the splash screen progress DT o that we have here this data transfer object has a value which is the progress from 0 to one and then a message that we can show in the user interface and I'm going to have to go back to that zaml file in just a moment because we didn't actually talk about a spot where we're going to show that if we continue looking through what we have this is where we have the progress being reported but who's responsible for making sure that happens first we need an instance of the thing that's going to report progress and there's a bunch of different ways you can do this you could have a dedicated object for it we could make a whole separate uh view model we could make a view model or um a user control associated with that I'm going to cheat a little bit here because you can go figure out how to apply these patterns for your particular case but I'm going to make the entire user control so that entire Splash Window is going to be able to report progress so I'm going to take Splash Window and pass it in and we have to go make sure that this thing can report progress now in order to make that happen I have this interface that I created you don't have to use an interface here we can go take this and just tack it on to the user control in this case I'm just going to do this and now if we go look at our Splash Window back over here it's already implementing this interface but it needs to have that method so that it can report progress and here I have this method to report progress and I'm cheating a little bit because I'm just going to set the text and the value of the progress text block in this progress bar to be the things that come off of progress info usually in WPF what we like to do is use view models for this type of thing and we have binding so what we could be doing instead is using a view model that has the progress reporting on it and then there's just a binding from this Splash Window to that view model I'm going to go back to the code over here and make sure that we have no compilation errors and at this point we should be pretty good to go again I'm not going to go through all the details of how this showing of the splash screen Works we're going to see if there's any issues with this and if I need to I'll go explain what's going on and instantly as soon as we go run this and try to show progress for the very first time we get an error and this was expected I plan for this and that's what's going to be behind door number one here but this says the calling thread cannot access this object because a different thread owns this and if you think about it in our splash screen we want to be doing background work we want that to be done on a different thread that's the whole point of it we have this beautiful magenta splash screen we have this important background work being done but now we're saying look I want to be able to report my progress along the way that progress reporting needs to happen on the user interface thread because we're updating the user interface so the fact of the matter is that this code right now is currently running on a background thread and we cannot update the user interface so let's go see how we fix this we can use our handy friend dispatcher to be able to invoke things on the main thread so all that I've done is taken these two lines and I've wrapped them in this dispatcher in vote call and this will force things to be run on the main thread it's just something importantly you have to think about when you're designing your applications because it's not obvious where things are running and as soon as you start getting into multi-threaded stuff and things get more complicated you need to think about where you want stuff to run and control that cont context accordingly so if you have to keep scattering around you know dispatch or invoke in all of these different places and it doesn't feel like there's a pattern it's probably a good opportunity for you to rethink the execution flow and maybe sit down draw it out and decide which parts of your code should be running in the background make it very obvious and which parts should be running in the main UI thread and also make it very obvious right pit of success Force the people that are developing in your application to fall into the right patterns so this reporting should be done on the main thread but I think callers should be able to call report from anywhere we will make sure in this context that we're always going to go do the update on the main thread let's go see if this fixes it and there we go some progress along the way but where's our text did I go mess that up let's go see I didn't come back to here but you can see that I just hid the visibility of this thing we got this nice progress right in the middle we'll go run it one more time cuz I Know It sped past you the first time there is all of our progress being done from the background being updated in the foreground on that main UI thread and then our splash screen completely closes off now as I alluded to earlier in this video One enhancement we can go make to this code I'm sure there's many but one enhancement that we can go make is changing over from directly modifying the user interface controls over to using a view and binding so when that video is ready you can check that out up here thanks and I'll see you next time

Frequently Asked Questions

What is the main focus of this video?

In this video, I focus on how to implement progress bar updates in a WPF splash screen using asynchronous programming. I walk through the steps to transition from an indeterminate progress bar to one that reflects actual progress.

Why do I need to use the Dispatcher when updating the UI from a background thread?

You need to use the Dispatcher because UI updates must occur on the main thread in WPF. When you perform background work, the code runs on a different thread, and attempting to update the UI directly from there will result in an error. The Dispatcher allows you to invoke UI updates safely on the main thread.

What should I do if I want to improve the way I handle progress reporting in my application?

If you want to improve progress reporting, consider using a view model and data binding instead of directly modifying UI controls. This approach aligns with best practices in WPF and helps maintain a clean separation of concerns in your application.

These FAQs were generated by AI from the video transcript.
An error has occurred. This application may no longer respond until reloaded. Reload