Iron Suite for .NET
10個 .NET 程式庫。一個完整的文件套件。
如何在.NET 10中將HTML轉換為PDF
現代.NET開發人員在整合像IronPDF、IronOCR、IronWord和IronXL等程式庫時,經常會使用非同步程式設計。 這些產品經常執行長時間運行的任務,例如渲染PDF、處理OCR內容或生成大型試算表 - 保持應用程式響應的正確方法是使用C#中的CancellationToken進行基於取消的操作。
本文說明如何使用取消標記,方法如何接受標記,如何處理任務取消,並如何在適當的時機將這些模式整合到Iron Software的程式庫中。 我們還涵蓋了最佳實踐、資源管理,以及如何同時使用多個CancellationTokens。
為何在Iron Software工作負載中取消請求很重要

Iron Software工具通常執行非同步操作,例如:
- IronPDF HTML到PDF的轉換
- IronOCR長時間運行的OCR提取
- 在Background Services中構建IronWord或IronXL文件
- 在PDF生成之前的大型HttpClient網頁請求
這些可能是長時間運行的操作,當使用者點選取消按鈕、導航離開或呼叫程式碼發出取消請求時必須優雅地終止。
使用取消標記可以確保:
- 應用程式的響應性
- 更好的資源管理
- 非託管資源的受控釋放
- 符合協作式取消模型的清晰取消
了解C# CancellationToken基礎知識
C#提供了CancellationTokenSource類,可以建立CancellationToken標記。 一個新的CTS CancellationTokenSource()可以建立一個令牌,傳遞給非同步方法。
var cts = new CancellationTokenSource();
CancellationToken token = cts.Token;Dim cts As New CancellationTokenSource()
Dim token As CancellationToken = cts.TokenDim cts As New CancellationTokenSource()
Dim token As CancellationToken = cts.Token令牌是通過方法參數傳遞的:
public async Task ProcessPdfAsync(string html, CancellationToken token)public async Task ProcessPdfAsync(string html, CancellationToken token)Public Async Function ProcessPdfAsync(html As String, token As CancellationToken) As TaskPublic Async Function ProcessPdfAsync(html As String, token As CancellationToken) As Task在方法內,您會定期檢查:
token.ThrowIfCancellationRequested();token.ThrowIfCancellationRequested();token.ThrowIfCancellationRequested()token.ThrowIfCancellationRequested()或檢查IsCancellationRequested屬性:
if (token.IsCancellationRequested)
{
Console.WriteLine("Cancellation requested.");
return;
}if (token.IsCancellationRequested)
{
Console.WriteLine("Cancellation requested.");
return;
}If token.IsCancellationRequested Then
Console.WriteLine("Cancellation requested.")
Return
End IfIf token.IsCancellationRequested Then
Console.WriteLine("Cancellation requested.")
Return
End If這提供了一種協作式取消模式,只有當您的程式碼檢查標籤時,操作取消事件才會發生。
使用IronPDF搭配CancellationToken
IronPDF的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);
}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);
}Imports System
Imports System.Threading
Imports System.Threading.Tasks
Public Class PdfGenerator
Public Async Function BuildPdfAsync(html As String, token As CancellationToken) As Task(Of PdfDocument)
Console.WriteLine(vbCrLf & "[Generator] Starting PDF rendering process...")
Dim renderer As 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)
End Function
End ClassImports System
Imports System.Threading
Imports System.Threading.Tasks
Public Class PdfGenerator
Public Async Function BuildPdfAsync(html As String, token As CancellationToken) As Task(Of PdfDocument)
Console.WriteLine(vbCrLf & "[Generator] Starting PDF rendering process...")
Dim renderer As 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)
End Function
End Class範例主控台輸出

這顯示了一個支持多個點取消的公開非同步Task。 當取消發生時,方法會拋出OperationCanceledException,您可以在catch塊中處理。
使用IronOCR搭配CancellationToken
IronOCR長時間運行的掃描圖像操作也得益於內部的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);
}
}Imports System.Threading
Imports System.Threading.Tasks
Imports IronOcr
Public Class OcrProcessor
Private ReadOnly ocr As New IronTesseract()
Public Async Function ExtractTextAsync(path As String, token As CancellationToken) As Task(Of String)
' 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(Function() ocr.Read(path).Text, token)
End Function
End ClassImports System.Threading
Imports System.Threading.Tasks
Imports IronOcr
Public Class OcrProcessor
Private ReadOnly ocr As New IronTesseract()
Public Async Function ExtractTextAsync(path As String, token As CancellationToken) As Task(Of String)
' 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(Function() ocr.Read(path).Text, token)
End Function
End Class範例輸出

IronWord文件生成和IronXL試算表組裝以相同方式工作。 因為這些都是可取消的操作,協作式取消模式可避免阻塞UI執行緒或背景服務。
在長時間操作中定期檢查取消
一個常見模式是在迴圈中檢查取消:
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
}
}Imports System.Threading
Imports System.Threading.Tasks
Public Async Function LongRunningOperation(token As CancellationToken) As Task
For i As Integer = 0 To 999
token.ThrowIfCancellationRequested()
Await Task.Delay(10, token) ' Await Task.Delay helps cooperative cancellation
Next
End FunctionImports System.Threading
Imports System.Threading.Tasks
Public Async Function LongRunningOperation(token As CancellationToken) As Task
For i As Integer = 0 To 999
token.ThrowIfCancellationRequested()
Await Task.Delay(10, token) ' Await Task.Delay helps cooperative cancellation
Next
End Function這確保取消請求以適當和及時的方式處理,並且系統不浪費資源。
在IronPDF渲染前使用HttpClient的CancellationToken
在生成PDF之前進行網頁請求以獲取HTML時,請始終傳遞令牌:
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);
}Imports System.Net.Http
Imports System.Threading
Imports System.Threading.Tasks
Dim client As New HttpClient()
Public Async Function FetchHtmlAsync(url As String, token As CancellationToken) As Task(Of String)
Dim response = Await client.GetAsync(url, token)
If Not response.IsSuccessStatusCode Then
Throw New Exception("Error occurred while requesting content.")
End If
Return Await response.Content.ReadAsStringAsync(token)
End FunctionImports System.Net.Http
Imports System.Threading
Imports System.Threading.Tasks
Dim client As New HttpClient()
Public Async Function FetchHtmlAsync(url As String, token As CancellationToken) As Task(Of String)
Dim response = Await client.GetAsync(url, token)
If Not response.IsSuccessStatusCode Then
Throw New Exception("Error occurred while requesting content.")
End If
Return Await response.Content.ReadAsStringAsync(token)
End Function這確保如果使用者導航走開,HttpClient能及時取消。
.NET Core背景服務中的取消
.NET Core背景服務包含的內部CancellationToken會自動傳遞給ExecuteAsync方法。 在運行Iron Software工具時使用它:
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);
}
}Protected Overrides Async Function ExecuteAsync(stoppingToken As CancellationToken) As Task
While Not stoppingToken.IsCancellationRequested
Await ProcessPdfAsync("<h1>Hello</h1>", stoppingToken)
Await Task.Delay(5000, stoppingToken)
End While
End FunctionProtected Overrides Async Function ExecuteAsync(stoppingToken As CancellationToken) As Task
While Not stoppingToken.IsCancellationRequested
Await ProcessPdfAsync("<h1>Hello</h1>", stoppingToken)
Await Task.Delay(5000, stoppingToken)
End While
End Function這是伺服器端長時間運行任務的一般模式。
使用Iron Software搭配CancellationTokens的最佳實踐
-
始終將CancellationToken傳遞給非同步方法。
-
在迴圈中使用ThrowIfCancellationRequested。
-
優先使用await Task.Delay而不是緊密迴圈。
-
使用LinkedTokenSource結合多個令牌。
-
始終處理OperationCanceledException。
-
使用取消來改善資源管理和響應應用程式。
-
記住C#是面向物件的程式設計語言,因此要乾淨地設計您的取消方法和取消邏輯。
任務取消的高級考慮
為了確保這是一篇對任何.NET開發人員都有幫助的文章,此處是簡單補充部分,包含剩餘相關術語,同時強調最佳實踐。
在C#中,任務取消不是自動的; 它取決於您在方法內實現的取消邏輯。 必須檢查令牌屬性,並且返回給消費者的令牌應允許他們判斷操作是否已被取消或成功完成。 如果請求無法完成,系統仍應以適當和及時的方式優雅終止。
如果使用者介面觸發取消按鈕,則CancellationTokenSource上的取消方法將發出取消信號,您的程式碼應定期檢查token.IsCancellationRequested。 當操作取消事件發生時,您會釋放資源並將控制權返回給調用方。
像IronOCR掃描深層巢狀文件或IronXL生成大試算表這樣的長時間運行操作應該在每一層中傳遞CancellationToken。 當使用者離開頁面時,操作應干淨結束。
Iron Software的產品使這變得更容易,因為它們本地遵循.NET的非同步程式設計模型。 當撰寫自己的程式庫時,考慮遵循相同的最佳實踐,以便您的消費者可以及時取消操作,而不會出現記憶體洩漏或持有非管理資源。
結論
使用C# CancellationToken與IronPDF、IronOCR、IronWord和IronXL 提供一種協作取消的方法,使應用程式保持響應、效率和健壯。通過在非同步程式設計中應用最佳實踐,將標記傳遞給非同步任務並定期檢查取消,您可以建立更快、更安全且更易於維護的.NET應用程式,當需要時能夠優雅終止。