The Task class is part of the Task Parallel Library (TPL) in System.Threading.Tasks. Introduced in .NET Framework 4.0, it provides a higher-level abstraction for asynchronous programming and parallelism. It allows operations to run in the background or in parallel with other tasks without blocking the main thread. Additionally, it supports cooperative task cancellation, making parallel programming, multithreading, exception handling, and result retrieval more manageable.
Key Features of the Task Class
- Supports cooperative task cancellation using a cancellation token.
- Eliminates the need for manual thread synchronization (e.g., Mutex or Monitor), unlike the Thread class.
- Utilizes the thread pool for efficient task management, improving performance for I/O-bound and CPU-bound operations.
- Provides AggregateException for structured error handling, unlike manual exception management in Thread.
- Easily integrates with async/await, supports parallel execution, and efficiently manages threads via the thread pool.
Example: In this example, we use a task class and pass an action to it, which returns a result.
C#
// C# program to demonstrate the use of
// Task class for asynchronous execution
using System;
using System.Threading.Tasks;
class Geeks
{
static void Main()
{
int num1 = 3;
int num2 = 5;
int num3 = 7;
// Creating a Task using the constructor
// that takes a Func<TResult> delegate
Task<int> task = new Task<int>(() => {
return Multiply(num1, num2, num3);
});
// Start the task
task.Start();
// Wait for the task to complete and get the result
task.Wait();
Console.WriteLine($"Task result: {task.Result}");
}
static int Multiply(int a, int b, int c)
{
return a * b * c;
}
}
Explanation: In the above example, we use a task class constructor Task<int> with a Func<int> delegate to invoke the Multiply method asynchronously. The task is started with the task.Start(), and the program waits for the task to complete using the task.Wait(). It will return the result of the multiplication of three numbers.
Declaration of Task Class
The Task class in C# is declared as follows:
public class Task : IAsyncResult, IDisposable
It implements the IAsyncResult and IDisposable interfaces, enabling support for asynchronous operations and resource management. The Task class provides various constructors, properties, and methods to manage asynchronous execution, handle exceptions, and coordinate task completion efficiently.
Constructors
Constructor | Description |
---|
Task(Action action) | This constructor initializes a task with the specific action passed on the argument. |
Task(Action action, CancellationToken cancellationToken) | This constructor initializes the task with the action and the cancellation token which makes sure that the task will be cancelled at the specific time |
Task(Action action, TaskCreationOptions creationOptions) | This constructor initializes the task with the action. This constructor allows us to control the scheduling of the task using the provided task creation options (e.g., LongRunning or DenyChildAttach). |
Task(Action action, CancellationToken cancellationToken, TaskCreationOptions creationOptions) | This constructor initializes the task with the action, CancellationToken and creation options. Useful for customizing the task creation, such as specifying if the task should be executed on a separate thread pool. |
Task(Action<object?> action, object? state) | This constructor creates a task with the action task with the specified action and an object state. The state parameter is used to pass state information to the action when the task executes. |
Task(Action<object?> action, object? state, CancellationToken cancellationToken) | This constructor initializes the task with the action, object state, and CancellationToken. This allows the task to be cancelled if the token is signalled. |
Task(Action<object?> action, object? state, TaskCreationOptions creationOptions) | This constructor initializes the task with the action, state, and creation options. Useful for customizing the task creation, such as specifying if the task should be executed on a separate thread pool. |
Task(Action<object?> action, object? state, CancellationToken cancellationToken, TaskCreationOptions creationOptions) | This constructor initializes the task with the action task with the specified action, state, CancellationToken and creation options. Useful for the task that could be executed on a separate thread pool. |
Example: In this example, we use the Task(Action, CancellationToken) constructor to create a task and demonstrate task cancellation.
C#
// C# program to demonstrate task
// cancellation using CancellationToken
using System;
using System.Threading;
using System.Threading.Tasks;
class Geeks
{
static void Main()
{
// Create a CancellationTokenSource to manage cancellation
CancellationTokenSource cts = new CancellationTokenSource();
// Create a Task using the constructor
// Task(Action action, CancellationToken cancellationToken)
// takes Action and CancellationToken
Task task = new Task(() =>
{
for (int i = 0; i < 3; i++)
{
if (cts.Token.IsCancellationRequested)
{
Console.WriteLine("Task canceled!");
return;
}
Console.WriteLine($"Task is working... {i}");
Thread.Sleep(100);
}
}, cts.Token);
// Start the task
task.Start();
// Simulate some condition to cancel
// the task after 3 seconds
// Wait for 3 miliseconds
Thread.Sleep(300);
// Request cancellation
cts.Cancel();
// Wait for the task to complete
task.Wait();
}
}
OutputTask is working... 0
Task is working... 1
Task is working... 2
Explanation: In the above example, we use the Task(Action, CancellationToken) constructor which takes two parameters one is the action to perform and the cancellation token. The task is started, and after 300 milliseconds, the task is cancelled by calling cts.Cancel(). we use task.Wait() to ensure the task is completed before the program ends.
Methods
Method | Description |
---|
ConfigureAwait(Boolean) | This method used to configure the continuation of a task which should run on the same thread or a different one after the task is completed. |
ContinueWith(Action) | It is used to run a specified action after the task finishes and it will not return a result. |
ContinueWith(Func<Task, TResult>) | It runs a specified function after the task finishes and returns a result. |
Delay(Int32) | This method is used to initialize a task that on the time passed on the arguments as in milliseconds. |
Dispose() | This method releases all resources which are used by the task. |
FromCanceled(CancellationToken) | This method creates a task that has been marked as cancelled using a cancellation token. |
FromException(Exception) | This method initializes a task which is completed with an exception passed in the argument. |
FromResult(TResult) | It is used to create a task that is completed successfully with the result passed in the argument. |
GetAwaiter() | This method is used to retrieve an awaiter which provides the task that is awaited asynchronously. |
Run(Action) | This method is used to run an action and its return type is a task. |
Run(Func) | This method uses a specified function asynchronously and returns a task that will eventually return a result. |
RunSynchronously() | This method runs the task synchronously on the current thread. It is useful when we are working with multiple tasks at the same time. |
RunSynchronously(TaskScheduler) | Similar to the previous method but with the task scheduler and running the task synchronously. |
Start() | This method is used to start the ask and schedule it for execution. |
ToString() | This method is used to show the object(Task) in the string representation. |
Wait() | It is used to wait for the task to be completed until it is not completed. |
Wait(CancellationToken) | This method is used to wait for the task to complete execution And can pass a cancellation token passed in the argument for the manual cancellation. |
Wait(Int32) | This method is also used to wait for the task completion but we can specify the time in milliseconds in the argument.t |
WaitAll(IEnumerable) | This method is used to wait until all the provided tasks are completed their execution. |
WaitAll(ReadOnlySpan) | This method is used for all the provided task objects to complete execution, using a ReadOnlySpan. |
GetHashCode() | Generates a hash code (unique identifier) for the current task object. |
GetType() | It is used to retrieve the type of the current task object. |
MemberwiseClone() | This method is used to create a shallow copy of the current task object. |
ContinueWith(Action, TaskScheduler) | Executes a continuation after the task completes, and allows specifying the scheduler for the continuation. |
ContinueWith(Action, TaskContinuationOptions) | Executes a continuation based on specified options when the task is completed. |
ContinueWith(Action, Object) | Creates a continuation that executes once the task finishes and passes along extra data. |
Example: In this example, we use different methods of Task class to perform parallel operations.
C#
// C# program to demonstrate task cancellation,
// continuation, and synchronous execution
using System;
using System.Threading;
using System.Threading.Tasks;
class Geeks
{
static void Main()
{
// Create a CancellationTokenSource to manage cancellation
CancellationTokenSource cts = new CancellationTokenSource();
// Create a Task using the constructor
// Task(Action action, CancellationToken cancellationToken)
// takes Action and CancellationToken
Task task = new Task(() =>
{
for (int i = 0; i < 3; i++)
{
if (cts.Token.IsCancellationRequested)
{
Console.WriteLine("Task was canceled!");
return;
}
Console.WriteLine($"Task is working... {i}");
Thread.Sleep(100);
}
}, cts.Token);
// Start the task
task.Start();
// Create a continuation task that runs
// when the first task completes
Task continuationTask = task.ContinueWith(t =>
{
if (t.IsCanceled)
{
Console.WriteLine("Continuation: Task was canceled.");
}
else
{
Console.WriteLine("Continuation: Task completed.");
}
});
// Simulate some condition to cancel the
// task after 300 milliseconds
Thread.Sleep(300);
cts.Cancel();
// Wait for the task to complete
try
{
task.Wait();
}
catch (AggregateException ex)
{
if (ex.InnerExceptions[0] is TaskCanceledException)
{
Console.WriteLine("Caught TaskCanceledException.");
}
}
// Wait for the continuation task to complete
continuationTask.Wait();
// Create and run a task synchronously
Task syncTask = new Task(() =>
{
Console.WriteLine("Running task synchronously.");
});
syncTask.RunSynchronously();
Console.WriteLine("Main thread is not blocked.");
}
}
OutputTask is working... 0
Task is working... 1
Task is working... 2
Continuation: Task completed.
Running task synchronously.
Main thread is not blocked.
Explanation: In the above example, use the methods task.start() to begin our task and then use Task.ContinueWith() to create a continuation task that runs when the original task is completed.
Properties
Property | Description |
---|
Id | This property is used to find the ID of the Task. |
CurrentId | This property is used to check the ID of the currently executing Task. |
Exception | This property is used to check AggregateException that caused the Task to end prematurely. |
Status | This property is used to check the current status of the Task. |
IsCanceled | This property is used to check the Task has been completed due to being cancelled. |
IsCancellationRequested | Checks if a cancellation has been requested for this Task. |
CancellationToken | Used to check if CancellationToken is associated with the current Task. |
IsCancellationAcknowledged | This property is used to find whether the Task has acknowledged cancellation. |
IsCompleted | This property is used to check if the task is completed or not |
IsCompletedSuccessfully | This property is used to find Task has been completed successfully or not. |
CreationOptions | This property is used to find TaskCreationOptions used to create the current Task. |
AsyncState | This property is used to check the object supplied when the Task was created. |
CompletedSynchronously | It is used to check the Task completed synchronously. |
Factory | Retrieves the default TaskFactory instance. |
CompletedTask | Used to retrieve the Task that has already been completed successfully. |
CompletedEvent | This property is used to retrieve ManualResetEventSlim which is set when the Task completes. |
ExceptionRecorded | This property is used to check an exception has been recorded for the current Task. |
Example: In this example, we use the Id, Status and IsCanceled properties of Task class.
C#
// C# program to demonstrate task properties
using System;
using System.Threading;
using System.Threading.Tasks;
class Geeks
{
static void Main()
{
// Create a CancellationTokenSource
// to manage cancellation
CancellationTokenSource cts = new CancellationTokenSource();
// Create a Task using the constructor
Task task = new Task(() =>
{
for (int i = 0; i < 3; i++)
{
if (cts.Token.IsCancellationRequested)
{
Console.WriteLine("Task was canceled!");
return;
}
Console.WriteLine($"Task is working... {i}");
Thread.Sleep(100);
}
}, cts.Token);
// Start the task
task.Start();
// Display task properties
Console.WriteLine($"Task ID: {task.Id}");
Console.WriteLine($"Task Status: {task.Status}");
Console.WriteLine($"Task IsCompleted: {task.IsCompleted}");
// Simulate some condition to cancel
// the task after 300 milliseconds
Thread.Sleep(300);
cts.Cancel();
// Wait for the task to complete
try
{
task.Wait();
}
catch (AggregateException ex)
{
if (ex.InnerExceptions[0] is TaskCanceledException)
{
Console.WriteLine("Caught TaskCanceledException.");
}
}
Console.WriteLine($"Task IsCompleted: {task.IsCompleted}");
}
}
OutputTask ID: 1
Task is working... 0
Task Status: Running
Task IsCompleted: False
Task is working... 1
Task is working... 2
Task IsCompleted: True
Explanation: In the above example, we use the properties like task.Id which shows the ID of the task which is 1 and then the task.Status which shows the status which is Waiting to run and we use task.IsCompleted which shows false because the task is not completed and then we use Task.IsCompleted which returns true because the task is completed successfully.
Similar Reads
C# Stack Class
In C#, the Stack<T> class represents a Last-in-First-out (LIFO) collection of objects. The stack is the part of the System.Collections.Generic namespace. This class allows us to push elements onto the stack, pop elements from the stack, and peek at the top element without removing it.The capac
5 min read
C# Thread Class
In C#, multi-threading is implemented using the Thread class, which is part of the System.Threading namespace. This class allows for the creation, management, and control of threads within an application. The Thread class provides various methods and properties to handle thread execution, prioritize
7 min read
C# Delegates
A delegate is an object which refers to a method or you can say it is a reference type variable that can hold a reference to the methods. It provides a way which tells which method is to be called when an event is triggered. For example, if you click on a Button on a form (Windows Form application),
6 min read
C# Main Thread
In C#, threads are the smallest units of execution that allow parallel execution of code, enabling multiple tasks to run concurrently within a single process. The Thread class in the System.Threading namespace is used to create and manage threads. In C#, the Main method is the entry point of any con
5 min read
Task Parallel Library in C#
In C#, Task Parallel Library (TPL) is a collection of APIs that provides more control over parallel and asynchronous programming. It is present in the System.Threading.Tasks namespace. TPL simplifies multithreading by managing thread scheduling and execution efficiently. It includes features like da
9 min read
C# Types of Threads
Multithreading is one of the core features in C# that allows multiple tasks to be performed concurrently. Threads allow your application to run multiple tasks simultaneously, improving performance, and resource utilization. In C#, there are two types of threads.Foreground ThreadsBackground ThreadsNo
4 min read
How to Create Threads in C#?
Multithreading enables concurrent task execution in C#. It improves performance and responsiveness. We can create threads using the System.Threading namespace. With the help of Threads, we can achieve multitasking and can define their behavior using different methods provided by the Thread Class. Ex
6 min read
C# Lifecycle and States of a Thread
In C#, threads enable the concurrent execution of tasks, it improves application performance and responsiveness. Understanding the lifecycle and states of a thread is essential for managing and synchronizing threads efficiently. A thread in C# can exist in one of the following states at any given ti
4 min read
C# Multithreading
C# is a multi-paradigm programming language that supports several programming styles, including procedural, object-oriented, and functional programming. One of the essential features of C# is its support for multithreading, which enables developers to write applications that can perform multiple tas
9 min read
C# | Thread(ThreadStart) Constructor
Thread(ThreadStart) Constructor is used to initialize a new instance of a Thread class. This constructor will give ArgumentNullException if the value of the parameter is null. Syntax: public Thread(ThreadStart start); Here, ThreadStart is a delegate which represents a method to be invoked when this
2 min read