C# Task

In c#, task is useful to perform the operations asynchronously on thread pool threads, 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 System.Threading.Tasks namespace, we can create or access the task objects by using the Task class.

 

Generally, the Task class will represent a single operation, and that will execute asynchronously on a thread pool thread rather than synchronously on the main application thread.

C# Create Task

In c#, we can create a task object by using Task class. Following is the example of creating a task object by using Task class and starting it by calling the Start method of Task class.

 

// Create a Task
Task t1 = new Task(PrintInfo);
// Start the task
t1.Start();

In the above code snippet, we create a task object (t1) and start it using the Start method. Instead, we can also create a task object which will start automatically either by using Factory property or Run method like as shown following.

 

// Create a started task using Factory
Task t2 = Task.Factory.StartNew(PrintInfo);

Or

// Creating a started task using Task.Run
Task t3 = Task.Run(() => { PrintInfo(); });

Like this, we can create the task objects in a variety of ways based on our requirements. In a performance point of view, the Task.Run or Task.Factory.StartNew methods are preferable to create and schedule the computational tasks.

 

In case if you want to separate the task creation and scheduling, then it's preferred to create the task separately using Task class and call the Task.Start method to schedule the task execution for a later time.

C# Task Example

Following is the example of creating and starting the task using Task class in c#.

 

using System;
using System.Threading.Tasks;

namespace TutlaneExamples
{
   class Program
   {
      static void Main(string[] args)
      {
         Task t1 = new Task(PrintInfo);
         t1.Start();
         Console.WriteLine("Main Thread Completed");
         Console.ReadLine();
      }
      static void PrintInfo()
      {
         for (int i = 1; i <= 4; i++)
         {
            Console.WriteLine("i value: {0}", i);
         }
         Console.WriteLine("Child Thread Completed");
      }
   }
}

If you observe the above example, we created a task object (t1) using Task.Run method to start the task immediately. Here, the task object (t1) will create a separate child thread to execute the defined functionality asynchronously on a thread pool.

 

When we execute the above example, we will get the result as shown below.

 

Main Thread Completed
i value: 1
i value: 2
i value: 3
i value: 4
Child Thread Completed

If you observe the above result, the task object has created a new child thread to handle the execution of functionality. Both threads (Main and child) started their execution simultaneously (asynchronously). The child thread continued its execution until it finishes its task even after completion of Main thread execution.

 

If we want to make the Main thread execution wait until the other tasks complete their execution, we can achieve this by using Task class properties and methods.

C# Task Properties

The following table lists some of the most commonly used properties of Task class to work with threads in c#.

 

PropertyDescription
CurrentId It will provide the ID of the currently executing task.
Status It will return the Task status.
IsCanceled It will return a value that indicates whether the task was canceled or not.
IsCompleted It will return a value that indicates whether the task was completed or not.
IsFaulted It will return a value that indicates whether the task stopped due to an unhandled exception or not.
Factory It provides access to factory methods for creating and configuring tasks.
Exception It will return the exceptions that caused the Task to end prematurely.

C# Task Methods

The following table lists some of the most commonly used methods of Task class to perform multiple tasks asynchronously in c#.

 

MethodDescription
ConfigureAwait() We can configure to use the await keyword to await the Task.
ContinueWith() It is useful to create a continuation of tasks.
Start() It is useful to start the Task.
Run() It will queue the specified work to run on the thread pool.
RunSynchronously() It will run the Task synchronously on the current TaskScheduler.
Delay() It will create a task that completes after a specified number of milliseconds.
Wait() It will make to wait for the Task to complete execution.
WaitAll() It will make waits for all of the provided Task objects to complete execution.
WaitAny() It will make waits for any of the provided Task objects to complete execution.
Dispose() It will release all the resources used by the current instance of the Task class.

C# Wait for Task to Complete

As discussed, the tasks will run asynchronously on the thread pool thread. The thread will start the task execution asynchronously along with the main application thread as soon as the task has been instantiated.

 

In the above example, the child thread continued its execution until it finishes its task even after completion of Main thread execution.

 

If we want to make the Main thread execution wait until the other tasks complete their execution, we can achieve that by using Task.Wait method. The Wait method will block other executions until the assigned task has completed its execution.

 

Following is the example of using the Wait() method to make the program execution wait unconditionally until the task completes its execution.

 

using System;
using System.Threading.Tasks;

namespace TutlaneExamples
{
   class Program
   {
      static void Main(string[] args)
      {
         Task t1 = Task.Run(() =>
         {
            PrintInfo();
         });
         t1.Wait();
         Console.WriteLine("Main Thread Completed");
         Console.ReadLine();
      }
      static void PrintInfo()
      {
         for (int i = 1; i <= 4; i++)
         {
            Console.WriteLine("i value: {0}", i);
         }
         Console.WriteLine("Child Thread Completed");
      }
   }
}

If you observe the above example, we used the Wait() method for task “t1” object. So, the Main thread execution will wait until the task object (t1) completes its execution.

 

When we execute the above program, we will get the result as shown below.

 

i value: 1
i value: 2
i value: 3
i value: 4
Child Thread Completed
Main Thread Completed

If you observe the above result, the main application thread waited until the execution of the task complete.

C# Task Overview

Following are the important points that you need to remember about tasks in c#.

 

  • In c#, the task is useful to perform the operations asynchronously on thread pool threads.
  • To work with task objects, we need to import System.Threading.Tasks namespace in our program.
  • In c#, we can create or access the task objects by using Task class.
  • The Task class will represent a single operation, which will execute asynchronously on a thread pool thread rather than synchronously on the main application thread.