Task

What is a Task in C# and why do we need it?

Why do we need a Task?

There are situations where we do not want to block the entire application because of a long running operation within it. Such operations were traditionally performed on a separate Thread. We will not discuss threads here, but just be informed that using threads is syntax heavy and it also makes it difficult to read the code and understand it. As C# evolved, it made it easier to use threads and hence came Task.

Let us consider a scenario

Let us create a simple WinForms app to let the user download a file when he clicks download button.

Take 1: Everything on the same thread

With the below code in place, click the download button and try to minimize or move the form, what do you notice?

private void button1_Click(object sender, EventArgs e)
{
    DownloadFile();
    MessageBox.Show("Download complete");
}

public static void DownloadFile()
{
    //simulating delay!
    Console.Beep(1500, 5000);            
}

You need to try out these code snippets in a Windows Forms project (.NET Framework) in Visual Studio to understand them better!

We noticed that the UI was frozen until the download function completed, right? This is not expected from an app. We need to keep the UI always responsive.

Take 2: Download function in a separate thread using Task

Let's try and do the same, this time in a separate thread, using a Task, as shown below. What do you notice this time?

private void button1_Click(object sender, EventArgs e)
{
    //DownloadFile();
    Task.Run(DownloadFile);
    MessageBox.Show("Download complete");
}

Make sure you put using System.Threading.Tasks; on the top of the file. More about Task in a while

This time around, we see that the app does not freeze during the download, but somethings not completely right - The message pops up even before the download is actually complete! Why did that happen? That’s because the Main thread does not wait for the task to complete. No one told it to wait, so it just executed other statements sequentially, like it always does. We will see in next topic on how we can make the UI thread wait for a task without blocking the app. Before that, let’s know a thing or two about Task

What is a Task in C#?

In C#, task is used to perform operations asynchronously on thread pool, and it was introduced in .NET Framework 4.0. To work with task objects, we need to import System.Threading.Tasks namespace in our program. Once we import it, we can create or access the task objects by using the Task class.

Syntax for creating a task

Task.Run(functionName) //only function name, no parenthesis!

    //or using anonymous function
    
Task.Run(() => {//function_body}) //braces optional if only one line of body

There are many options available for working with Tasks, we will not discuss those in the interest of time. Next we will see how to make the Main thread (UI Thread) await for the Task to complete.

Additional reading

https://www.tutlane.com/tutorial/csharp/csharp-task

Last updated