使用IRON SUITE

使用Iron Software程式庫的C# CancellationToken

現代 .NET 開發者在整合像 IronPDFIronOCRIronWordIronXL 這樣的程式庫時,經常會使用非同步程式設計。 這些產品經常執行長時間運行的任務——例如渲染PDF、處理OCR內容或生成大型試算表——而保持應用程式響應的正確方法是使用基於C# CancellationToken的取消。

本文將解釋如何使用取消標記,方法如何接受標記,如何處理任務取消,以及如何在合適的時間點將這些模式整合到Iron Software的程式庫中。 我們還涉及最佳實踐、資源管理和如何同時使用多個CancellationTokens。

在Iron Software工作負載中取消請求為何重要

Iron Software

Iron Software 工具經常運行非同步操作——例如:

這些可能是長時間運行的操作,當使用者點擊取消按鈕、導航離開或呼叫代碼發出CancellationRequest時,必須優雅地終止。

使用取消標記可確保:

  • 反應迅速的應用程式
  • 更好的資源管理
  • 未管理資源的受控釋放
  • 乾淨的合作取消模型

理解 C# CancellationToken 基本概念

C# 提供了 CancellationTokenSource 類,這個類可以創建 CancellationToken 標記。 一個 CTS new CancellationTokenSource() 可以創建一個傳遞給非同步方法的標記。

var cts = new CancellationTokenSource();
CancellationToken token = cts.Token;
var cts = new CancellationTokenSource();
CancellationToken token = cts.Token;
Dim cts As New CancellationTokenSource()
Dim token As CancellationToken = cts.Token
$vbLabelText   $csharpLabel

標記通過方法參數傳遞下來:

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 Task
$vbLabelText   $csharpLabel

在方法內,您需要定期檢查:

token.ThrowIfCancellationRequested();
token.ThrowIfCancellationRequested();
token.ThrowIfCancellationRequested()
$vbLabelText   $csharpLabel

或者檢查 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 If
$vbLabelText   $csharpLabel

這提供了一種合作取消模式,取消事件僅在您的代碼檢查標記時發生。

將 CancellationToken 用於 IronPDF

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 Class
$vbLabelText   $csharpLabel

範例控制台輸出

控制台輸出

這顯示了支援取消操作的公開非同步任務,在多個點發出取消支持。 當取消發生時,該方法會拋出OperationCanceledException,在catch區塊中處理該異常。

將 CancellationToken 用於 IronOCR

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 Class
$vbLabelText   $csharpLabel

範例輸出

IronOCR與CancellationTokens的使用範例

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 Function
$vbLabelText   $csharpLabel

這確保了取消請求以合適和及時的方式得到處理,並且系統不會浪費週期。

在 IronPDF 渲染前使用 CancellationToken 與 HttpClient

在生成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 Function
$vbLabelText   $csharpLabel

這確保如果使用者導航離開,HttpClient能夠及時取消。

.NET Core 背景服務中的取消

.NET Core 背景服務包括一個自動傳遞給 ExecuteAsync 方法的內部 CancellationToken。 使用它來運行 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 Function
$vbLabelText   $csharpLabel

這是伺服器端長時間運行任務的一般模式。

Iron Software 使用取消標記的最佳實踐

  • 始終將 CancellationToken 傳遞給非同步方法。

  • 在迴圈內使用 ThrowIfCancellationRequested。

  • 優於緊密迴圈地使用 await Task.Delay。

  • 與 LinkedTokenSource 組合標記。

  • 始終處理 OperationCanceledException。

  • 使用取消更好地管理資源和提供響應的應用程式。

  • 記得 C# 是物件導向程式設計語言,因此請設計您的取消方法和取消邏輯。

任務取消的高級考量

為了確保這是對任何 .NET 開發者有用的文章,下面是一個簡短的補充部分,其中包含剩餘的相關術語,同時強調了最佳實踐。

C# 中的任務取消不是自動的; 它取決於您在方法內部實現的取消邏輯。 必須檢查標記屬性,並且返回給消費者的標記應允許他們確定操作是否已被取消或成功完成。 如果請求無法完成,系統仍應以合適和及時的方式中止。

如果用戶界面觸發取消按鈕,您的 CancellationTokenSource 上的取消方法將發出取消信號,並且您的代碼應通過 token.IsCancellationRequested 進行定期檢查。 當操作取消事件發生時,您將釋放資源並將控制權返回給呼叫者。

IronOCR 扫描深层嵌套文档或IronXL 生成庞大试算表等長時間運行的操作應在每一層中傳遞CancellationToken。 當用戶從頁面導航離開時,應操作應潔淨地結束。

Iron Software 產品讓這個過程更容易,因為它們自然地遵循 .NET 的非同步程式設計模式。 在撰寫您自己的程式庫時,考慮遵循相同的最佳實踐,以便您的消費者能夠及時取消操作,而不會洩漏記憶體或持有未管理的資源。

結論

使用 C# CancellationToken 與 IronPDFIronOCRIronWordIronXL 提供了一種合作取消的方法,使應用程式保持響應、效率和穩定。通過應用非同步程式設計中的最佳實踐,將標記傳遞給非同步任務,並定期檢查取消,您可以構建更快速、更安全和更易於維護的 .NET 應用程式,在需要時能夠潔淨地終止。