Hey, everyone. This is Brian Lagunas and in this video, I'm going to show you how to implement some multi-threading and report the progress of that long-running process to your end users, using the new Xam BusyIndicator Control, just released with the Infragistics Ultimate 15.2 WPF controls.
[youtube] width="420" height="315" src="http://www.youtube.com/embed/-uVJ6utvRhk" [/youtube]
What we have here is an application that has one view and a view model. This view is very simple. It contains a list box that this is bound to a collection of items, and then we have a button that will kick off the process of creating those items. We are using Prism’s view model locator to set the data context of the view model, so let's take a look at the view model. As you can see, we have a property, a list of string that will represent the items that we're creating. We have our command, called start process command, that is bound to the button in our UI. When this button is clicked, the command will be invoked and we will generate ten million items to be added to this list of strings, in which our list box is bound to.
If we run the application as it is, we can see that we have our list box here, there's nothing go on. Then I'm going to click the start process button. I can see immediately our UI is frozen, I can't move anything around, I don't know what's going on, as an end user it's just stuck. When the process is complete, the UI becomes responsive again, and now I can see the items we've created. This is not what we want. What we're going to do is first we're going to create a multi-threaded environment. We're going to take what we currently have, and make it multi-threaded. We're going to use this using the new Async 08 features in dot net.
First, let's go ahead and convert this generate items method into an asynchronous method. I'm going to do that by creating a new task, I'm just going to wrap what we already have in a task, and then we have to return a task. We're going to say, "returntask.run," and then we're going to wrap our current logic inside of that task.run. The next thing we're going to do is come up to the start process method, add the async, and then add a wait just before our generate items. Now let's run this application again.
Let's see what happens when I click the start process button. As you can see, the UI remains responsive. I don't know exactly what's going on, because I clicked the button... Oh, something is happening. Apparently something was going on in the background. This is because we took that long-running process and stuck it on a separate thread, so our UI remained responsive. The next step is to let our end user know that, hey, something is happening, there is a process going on, so don't click everywhere. Be patient, and then you will see the results of that process.
To do that, we're going to modify our UI to utilize the new Xaml BusyIndicator Control that just released with our WPF controls. I go into my toolbox, I'm going to find the Xaml BusyIndicator. I'm just going to drag it into my view, then what I'm going to do is I'm going to actually wrap our current view with the Xaml BusyIndicator. In order to get the Xaml BusyIndicator to show, we have to bind the is busy property to a property in our view model. We'll assume this is called "is busy." That means we have to go to our view model, and we have to add a new property. It's going to be a bullion called "is busy." Next, we're going to set is busy to true before we start our process, and then set it to false when the process has completed. Let's run the application.
Now I'm going to start process, and now we can see something is going on. There is a process going on in the background, my UI remains responsive, but as an end user, I know that something is happening, and now that the BusyIndicator has disappeared, our results are displayed to us. Let's say I'm not happy with that animation. The BusyIndicator actually has a number of animations to choose from. It actually ships with eight, we have azure, gears, progress bar, progress ring, let's just stick with the azure. Let's go azure.
Now we have the azure animation. I'm just going to run the app, and I'm going to start the process again, and now we have a new animation. You can see that the start process button has been grayed out because the BusyIndicator is covering all the interaction points so that our end users are not confused. What's really cool is we can modify that azure animation to say, "You know what, I want the top element to be green, or the lower elements to be green, and we'll make the top ones red." We're changing the colors of the animation. As you can see, those colors are reflected when the animation is shown.
Now that we have the ability to show the BusyIndicator and play with the animation and change colors of the animation, let's go back and report the progress. Currently what we have is called an indeterminate animation. The animation keeps spinning and spinning and spinning, we have no idea when it's going to finish, we just know something's occurring. Let's say that we know how far we are into the process. We have a number of records, and we know how many records have been created. I want to report the progress of where we are at to the end user. First, let's start by reporting progress from our asynchronous operation. Let's start by creating a new I progress of T, which will be a double. We'll make it a new progress. Then, in this update progress, here, we're going to pass the percentage in order to update the UI. That means we need a new property. This is going to be a double. Then in here, we will set progress equals to the percentage. Now, calculating this percentage is even easier. Basically going to say, "If I mod, let's say 1500 equals 0, we're going to divide I by the maximum number of records to get the percentage of complete." Then we're going to take our progress and report that percentage. Now, the reason we do this is because we don't want to flood our UI with update messages. We just want to update every now and then.
The next step is to update our UI. First, let's go ahead and change our animation. We need an animation that shows progress. Let's go to progress ring. Now we want to set the property is indeterminate equal to false, because now we have a determinate state that we want to manage. Then we take the progress value and we create a binding the progress property that we're updating in the view model. Let's run the application. Start the process. Now there we can see the UI is updated with the percentage complete of the current task we are running. When it hits 100 percent, the results are displayed to our end users. That's all there is to it. As you can see, it's extremely easy to add multi-threading to your application and report the progress of that long-running process to your end users using the new Xam BusyIndicator Control now available with Infragistics Ultimate WPF controls.