Progress of a Task in C#

By default, Task doesn’t report its progress as a BackgroundWorker does. But that doesn’t mean we can’t get a progress of a Task. There is a new interface which was introduced with .NET framework 4.5 which is IProgress<T>. This interface exposes a Report(T) method, which the async task calls to report progress.

 

Let’s go by an example with the following async method.

async Task MyMethodAsync(int sleepTime, IProgress<MyTaskProgressReport> progress)
{
    int totalAmount = 10000; 
    for (int i = 0; i <= totalAmount;)
    {
        await Task.Delay(sleepTime);
        progress.Report(new MyTaskProgressReport { CurrentProgressAmount = i, TotalProgressAmount = totalAmount, CurrentProgressMessage = string.Format("On {0} Message", i) });
        i = i + sleepTime;
    }
}

It takes a progress parameter which is an IProgress of type “MyTaskProgressReport” and here is the “MyTaskProgressReport” class.

public class MyTaskProgressReport

{
   //current progress
   public int CurrentProgressAmount { get; set; }
   //total progress
   public int TotalProgressAmount { get; set; }
   //some message to pass to the UI of current progress
   public string CurrentProgressMessage { get; set; }
}

To simulate a time taking task inside the async method, there is a For Loop and inside is a Task Delay. In every iteration, progress is reported to the caller. Now let’ see how the UI captures this.

On the UI thread, we have to define an event handler Action<T>, which will be called when IProgress<T>.Report is invoked.

private void ReportProgress(MyTaskProgressReport progress)

{
    label1.Text = progress.CurrentProgressMessage;
    textBox1.Text = string.Format("{0} out of {1}", progress.CurrentProgressAmount, progress.TotalProgressAmount);
}

Now calling the async method with a Progress<T> instance, we invoke the async method which is triggered by a button click.

private async void button1_Click(object sender, EventArgs e)

{
    var progressIndicator = new Progress<MyTaskProgressReport>(ReportProgress);
    await MyMethodAsync(1000, progressIndicator);
}

Here is the output.

http://lh6.ggpht.com/-uCBzwOLh1Sk/UeLQ6bayRuI/AAAAAAAABrU/0w07Xdr_VxQ/image_thumb.png?imgmax=800
Result

A full sample is in the MSDN Code Gallery. Do check it out.
Download Sample

Happy Coding.