How to Cancel Parallel Operations in C#?
We can cancel operations in Parallel Programming using the Cancellation Token, like in Asynchronous Programming. The ability to stop parallel execution is provided via the ParallelOptions Class. The following will appear if you right-click on the ParallelOptions class and choose to view the definition. Three attributes and one constructor make up this class.
The constructor listed below is available in the C# ParallelOptions class and can be used to generate a ParallelOptions class instance.
- ParallelOptions(): It creates a fresh instance of the ParallelOptions class from scratch.
The ParallelOptions Class offers the following three attributes.
- Public int MaxDegreeOfParallelism {get; set;}: The maximum number of concurrent tasks allowed by the ParallelOptions object can be obtained or modified using this property. The maximum amount of parallelism is represented by the integer that is returned.
- Public CancellationToken CancellationToken {get; set;}: The CancellationToken connected to the ParallelOptions object can be obtained or set using this property. It gives back the token connected to the ParallelOptions instance.
How to Cancel Parallel Operations in C#?
We must first create an instance of the ParallelOptions class. Finally, in order to cancel the parallel operations in C#, we must set the CancellationToken properties of the ParallelOptions class to the token of the CancellationTokenSource instance. the syntax for stopping concurrent execution in C# using CancellationToken.
Canceling Parallel Operation Example using Parallel Foreach Loop in C#:
Program:
The following program will be:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace ParallelProgrammingDemo
{
class Program
{
static void Main(string[] args)
{
//Create an Instance of CancellationTokenSource
var CTS = new CancellationTokenSource();
//Set when the token is going to cancel the parallel execution
CTS.CancelAfter(TimeSpan.FromSeconds(5));
//Create an instance of ParallelOptions class
var parallelOptions = new ParallelOptions()
{
MaxDegreeOfParallelism = 2,
//Set the CancellationToken value
CancellationToken = CTS.Token
};
try
{
List<int> integerList = Enumerable.Range(0, 20).ToList();
Parallel.ForEach(integerList, parallelOptions, i =>
{
Thread.Sleep(TimeSpan.FromSeconds(1));
Console.WriteLine($"Value of i = {i}, thread = {Thread.CurrentThread.ManagedThreadId}");
});
}
//When the token is canceled, it will throw an exception
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
//Finally dispose the CancellationTokenSource and set its value to null
CTS.Dispose();
CTS = null;
}
Console.ReadLine();
}
}
}
OUTPUT:
The Output for the following program will be:
![How to Cancel Parallel Operations in C#?](https://static.tutorialandexample.com/csharp/how-to-cancel-parallel-operations-in-csharp1.png)
Canceling Parallel Operation Execution Example using Parallel For Loop in C#:
Program:
The following program will be:
using System;
using System.Threading;
using System.Threading.Tasks;
namespace ParallelProgrammingDemo
{
class Program
{
static void Main(string[] args)
{
//Create an Instance of CancellationTokenSource
var CTS = new CancellationTokenSource();
//Set when the token is going to cancel the parallel execution
CTS.CancelAfter(TimeSpan.FromSeconds(5));
//Create an instance of ParallelOptions class
var parallelOptions = new ParallelOptions()
{
MaxDegreeOfParallelism = 2,
//Set the CancellationToken value
CancellationToken = CTS.Token
};
try
{
Parallel.For(1, 21, parallelOptions, i => {
Thread.Sleep(TimeSpan.FromSeconds(1));
Console.WriteLine($"Value of i = {i}, thread = {Thread.CurrentThread.ManagedThreadId}");
});
}
//When the token is canceled, it will throw an exception
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
//Finally dispose the CancellationTokenSource and set its value to null
CTS.Dispose();
CTS = null;
}
Console.ReadLine();
}
}
}
OUTPUT:
The Output for the following program will be:
![How to Cancel Parallel Operations in C#?](https://static.tutorialandexample.com/csharp/how-to-cancel-parallel-operations-in-csharp2.png)
Note: Parallel programming uses all we learned about the Cancellation Token Source and Cancellation Token in asynchronous programming.
One of the most helpful classes while using multithreading is ParallelOptions. This class offers choices to stop the simultaneous execution of our code and options to limit the number of concurrently running threads.
The efficient use of many processor cores for concurrent work is made possible by parallel operations in C#, which improves performance. But occasionally, you must stop these actions because of user requests, timeouts, or other issues. You can accomplish this by using the CancellationToken and associated.NET framework features.
Step 1: Create a CancellationTokenSource:
A CancellationTokenSource (CTS) serves as the Cancellation's control element. It provides a means to notify linked tasks of Cancellation and manages the cancellation token (CancellationToken). Start your parallel process by creating a CancellationTokenSource.
Step 2: Obtain the CancellationToken:
You supply your parallel jobs with the CancellationToken from the CancellationTokenSource. They can use it to look for requests to cancel.
CancellationToken token = cts.Token;
Step 3: Create Parallel Tasks:
Use parallel programming structures like Task, Parallel. For, and Parallel.ForEach.Run to carry out multiple jobs at once.
ParallelOptions options = new ParallelOptions { CancellationToken = token };
Parallel.For(0, itemCount, options, i => {
// Your parallel task logic here
});
Step 4: Checking for Cancellation:
Utilizing the IsCancellationRequested feature of the CancellationToken, regularly check your parallel job to see if a cancellation request has been made.
if (token.IsCancellationRequested) {
// Clean up and exit gracefully
return;
}
Step 5: Request Cancellation:
Call the Cancel() method on the CancellationTokenSource to stop the parallel operations.
cts.Cancel();
Step 6: Handle Cancellation:
Once cleanup is complete, a job that has detected Cancellation should depart. To handle exceptions related to cancellations, you can also catch OperationCanceledException.
try {
// Your parallel task logic
} catch (OperationCanceledException ex) {
// Handle Cancellation
}
Step 7: Waiting for Completion:
You can use the Task to wait for all tasks to finish or until a certain timeout after requesting Cancellation.WhenAll technique.
try {
Task.WhenAll(task1, task2, task3).Wait();
} catch (AggregateException ex) {
// Handle exceptions from tasks
}
Step 8: Graceful Shutdown:
Make sure that cleanup is handled by your application even when Cancellation happens. Close connections, release any holding locks and dispose of resources.
Step 9: UI Interaction:
Provide an interface (such as a button) to cause Cancellation of concurrent tasks based on user input. Call the Cancel() function on the CancellationTokenSource when the user requests a cancellation.
Step 10: Advanced Scenarios:
Consider employing strategies like Task. Factory for more complicated cases. To manage Cancellation across several asynchronous actions, use StartNew, the async/await paradigm, and TaskCompletionSource.
Of course, let's go deeper into the specifics of C# parallel operation cancellation.
1. CancellationTokenSource:
The fundamental element for managing cancellations is the CancellationTokenSource class. It stands for the origin of the cancellation token, which is transferable across various assignments. All related tokens are signaled when Cancellation is requested through the source, enabling tasks to respond accordingly.
2. Cooperative Cancellation:
Because Cancellation in parallel processes is cooperative, tasks must actively monitor the status of the cancellation token. This guarantees that jobs can finish any necessary cleanup work before leaving and promptly reply to cancellation requests.
3. Task Cancellation:
Tasks can reply to a cancellation request in several ways:
If a cancellation is not requested, they can proceed normally.
When a cancellation is discovered, they can issue an OperationCanceledException, giving you a chance to respond to the Cancellation and carry out cleaning.
4. Graceful Cleanup:
When parallel activities are terminated, there is an opportunity for graceful cleanup, resource release, file or connection closure, and state integrity preservation.
5. Exception Handling:
Tasks may throw OperationCanceledException during Cancellation. These exceptions can be recognized and dealt with properly. Multiple exceptions during parallel execution can be handled with aggregate exceptions.
6. Task. Wait and Task.WhenAll:
To wait for task completion after requesting Cancellation, you can use the Task. Wait method or Task.WhenAll. These methods allow you to await the completion of all tasks, catching exceptions if any occur.
7. Timeout and Cancellation:
Timeouts can be combined with Cancellations to ensure that tasks do not run indefinitely. By using a combination of Tasks.WhenAny and a Task. Delay, you can implement timeouts on parallel operations.
8. User Interaction:
You can link the cancellation source to UI events for user-initiated cancellations, such as when a user clicks a "Cancel" button. This provides a responsive user experience and allows users to interrupt lengthy computations.
9. Handling Long-Running Tasks:
For particularly long-running or asynchronous tasks, consider breaking them into smaller units, making it easier to check for Cancellation between these units.
Conclusion:
In conclusion, Managing the Cancellation of parallel activities in C# is essential for developing responsive and user-friendly apps, to sum up. The.NET framework's CancellationToken and CancellationTokenSource can gently cease running computations when appropriate by following the instructions. This lets you deal with cancellation-related situations such as user requests, timeouts, etc.
By implementing these strategies, you can ensure that your application is still reliable, effective, and quick to react to shifting needs or user interactions. The whole user experience is improved, and your parallelized code becomes more reliable and stable when Cancellation is handled correctly.