Using C# CancellationToken with Iron Software Libraries
Modern .NET developers often work with asynchronous programming when integrating libraries like IronPDF, IronOCR, IronWord, and IronXL. These products frequently run long running tasks—such as rendering PDFs, processing OCR content, or generating large spreadsheets—and the correct way to keep applications responsive is to use C# CancellationToken–based cancellation.
This article explains how to use cancellation tokens, how a method accepts a token, how to handle task cancellation, and how to integrate these patterns with Iron Software libraries in an appropriate and timely manner. We also cover best practices, resource management, and how to use multiple CancellationTokens simultaneously.
Why Cancellation Requests Matters in Iron Software Workloads

Iron Software tools often run asynchronous operations - for example:
An IronPDF HTML-to-PDF conversion
An IronOCR long-running OCR extraction
An IronWord or IronXL document build inside Background Services
- A large HttpClient web request before PDF generation
These can be long running operations that must gracefully terminate when a user clicks a Cancel button, navigates away, or when the calling code issues a CancellationRequest.
Using cancellation tokens ensures:
Responsive applications
Better resource management
Controlled release of unmanaged resources
- A clean cooperative cancellation model
Understanding C# CancellationToken Basics
C# provides the CancellationTokenSource class, which creates a CancellationToken token. A CTS new CancellationTokenSource() can create a token that is passed to async methods.
var cts = new CancellationTokenSource();
CancellationToken token = cts.Token;var cts = new CancellationTokenSource();
CancellationToken token = cts.Token;IRON VB CONVERTER ERROR developers@ironsoftware.comA token is passed down using a method parameter:
public async Task ProcessPdfAsync(string html, CancellationToken token)public async Task ProcessPdfAsync(string html, CancellationToken token)IRON VB CONVERTER ERROR developers@ironsoftware.comInside the method, you periodically check:
token.ThrowIfCancellationRequested();token.ThrowIfCancellationRequested();IRON VB CONVERTER ERROR developers@ironsoftware.comor inspect the IsCancellationRequested property:
if (token.IsCancellationRequested)
{
Console.WriteLine("Cancellation requested.");
return;
}if (token.IsCancellationRequested)
{
Console.WriteLine("Cancellation requested.");
return;
}IRON VB CONVERTER ERROR developers@ironsoftware.comThis provides a cooperative cancellation pattern where the operation cancelled event occurs only when your code checks the token.
Using CancellationToken with IronPDF
IronPDF’s HTML rendering is designed for asynchronous programming, so you can integrate cancellation naturally.
public async Task<PdfDocument> BuildPdfAsync(string html, CancellationToken token)
{
Console.WriteLine("\n[Generator] Starting PDF rendering process...");
var renderer = new ChromePdfRenderer();
token.ThrowIfCancellationRequested();
Console.WriteLine("[Generator] Simulating a 2-second delay...");
await Task.Delay(2000, token);
token.ThrowIfCancellationRequested();
Console.WriteLine("[Generator] Delay complete. Starting actual rendering...");
// This is the working overload for your library version
return await renderer.RenderHtmlAsPdfAsync(html);
}public async Task<PdfDocument> BuildPdfAsync(string html, CancellationToken token)
{
Console.WriteLine("\n[Generator] Starting PDF rendering process...");
var renderer = new ChromePdfRenderer();
token.ThrowIfCancellationRequested();
Console.WriteLine("[Generator] Simulating a 2-second delay...");
await Task.Delay(2000, token);
token.ThrowIfCancellationRequested();
Console.WriteLine("[Generator] Delay complete. Starting actual rendering...");
// This is the working overload for your library version
return await renderer.RenderHtmlAsPdfAsync(html);
}IRON VB CONVERTER ERROR developers@ironsoftware.comExample Console Output

This shows a public async Task that supports cancellation at multiple points. When cancellation occurs, the method throws an OperationCanceledException, which you handle in a catch block.
Using CancellationToken with IronOCR
IronOCR’s long running operation of scanning images also benefits from an internal CancellationToken:
public class OcrProcessor
{
private readonly IronOcr.IronTesseract ocr = new IronOcr.IronTesseract();
public async Task<string> ExtractTextAsync(string path, CancellationToken token)
{
// Check for cancellation immediately upon entering the method.
token.ThrowIfCancellationRequested();
// Run the synchronous OCR method on a background thread.
// This is the correct pattern for cancellable synchronous wrappers.
return await Task.Run(() => ocr.Read(path).Text, token);
}
}public class OcrProcessor
{
private readonly IronOcr.IronTesseract ocr = new IronOcr.IronTesseract();
public async Task<string> ExtractTextAsync(string path, CancellationToken token)
{
// Check for cancellation immediately upon entering the method.
token.ThrowIfCancellationRequested();
// Run the synchronous OCR method on a background thread.
// This is the correct pattern for cancellable synchronous wrappers.
return await Task.Run(() => ocr.Read(path).Text, token);
}
}IRON VB CONVERTER ERROR developers@ironsoftware.comExample Output

IronWord document generation and IronXL spreadsheet assembly work the same way. Because these are all cancelable operations, the cooperative cancellation pattern avoids blocking UI threads or Background Services.
Periodically Checking for Cancellation in Long Operations
A common pattern is to loop and check cancellation:
public async Task LongRunningOperation(CancellationToken token)
{
for (int i = 0; i < 1000; i++)
{
token.ThrowIfCancellationRequested();
await Task.Delay(10, token); // await Task.Delay helps cooperative cancellation
}
}public async Task LongRunningOperation(CancellationToken token)
{
for (int i = 0; i < 1000; i++)
{
token.ThrowIfCancellationRequested();
await Task.Delay(10, token); // await Task.Delay helps cooperative cancellation
}
}IRON VB CONVERTER ERROR developers@ironsoftware.comThis ensures cancellation requests are handled in an appropriate and timely manner, and the system does not waste cycles.
Using CancellationToken with HttpClient Before IronPDF Rendering
When performing a web request to fetch HTML before generating a PDF, always pass the token:
var client = new HttpClient();
public async Task<string> FetchHtmlAsync(string url, CancellationToken token)
{
var response = await client.GetAsync(url, token);
if (!response.IsSuccessStatusCode)
throw new Exception("Error occurred while requesting content.");
return await response.Content.ReadAsStringAsync(token);
}var client = new HttpClient();
public async Task<string> FetchHtmlAsync(string url, CancellationToken token)
{
var response = await client.GetAsync(url, token);
if (!response.IsSuccessStatusCode)
throw new Exception("Error occurred while requesting content.");
return await response.Content.ReadAsStringAsync(token);
}IRON VB CONVERTER ERROR developers@ironsoftware.comThis ensures that if the user navigates away, the HttpClient cancels in a timely manner.
Cancellation in .NET Core Background Services
.NET Core Background Services include an internal CancellationToken automatically passed to the ExecuteAsync method. Use it when running Iron Software tools:
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
await ProcessPdfAsync("<h1>Hello</h1>", stoppingToken);
await Task.Delay(5000, stoppingToken);
}
}protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
await ProcessPdfAsync("<h1>Hello</h1>", stoppingToken);
await Task.Delay(5000, stoppingToken);
}
}IRON VB CONVERTER ERROR developers@ironsoftware.comThis is the general pattern for server-side long-running tasks.
Best Practices for Using Cancellation Tokens with Iron Software
Always pass CancellationToken into async methods.
Use ThrowIfCancellationRequested inside loops.
Prefer await Task.Delay instead of tight loops.
Combine tokens with LinkedTokenSource.
Always handle OperationCanceledException.
Use cancellation for better resource management and responsive applications.
- Remember that C# is an object-oriented programming language, so design your cancellation method and cancellation logic cleanly.
Advanced Considerations for Task Cancellation
To ensure this is a good article for any .NET developer, here is a brief supplemental section that incorporates remaining relevant terminology while reinforcing best practices.
Task cancellation in C# is not automatic; it depends on cancellation logic implemented inside your method. The token property must be checked, and the token returned to consumers should allow them to determine whether the operation has been canceled or successfully completed. If a request cannot finish, the system should still gracefully terminate in an appropriate and timely manner.
If a user interface triggers a cancel button, the cancel method on your CancellationTokenSource will signal cancellation, and your code should periodically check via token.IsCancellationRequested. When operation cancelled events occur, you free resources and return control to the caller.
A long running operation like IronOCR scanning deeply nested documents or IronXL generating massive spreadsheets should pass the CancellationToken throughout every layer. When user navigates away from the page, the operation should end cleanly.
Iron Software products make this easier because they follow the .NET asynchronous programming model natively. When writing your own libraries, consider following the same best practices so that your consumers can cancel operations in a timely manner without leaking memory or holding onto unmanaged resources.
Conclusion
Using C# CancellationToken with IronPDF, IronOCR, IronWord, and IronXL provides a cooperative cancellation approach that keeps applications responsive, efficient, and robust. By applying best practices in asynchronous programming, passing tokens to async tasks, and periodically checking for cancellation, you can build faster, safer, and more maintainable .NET applications that gracefully terminate when needed.