Iron Suite for .NET
10个.NET库。一整套文档。
using Iron Software 库中的 C# CancellationToken

现代软件开发要求速度、响应速度和无与伦比的可扩展性。 在网络应用程序和企业解决方案的世界里,阻塞用户界面线程或占用服务器资源是根本无法接受的。 这就是异步编程,由强大的C#中的async和await关键字驱动,不再只是一个特性,而是一个必需的架构基础。
对于利用高性能库的开发者,比如用于PDF生成、图像处理和OCR的Iron Software套件,理解如何编写异步代码是构建高效代码的关键,这些代码充分利用.NET任务并行库的全部力量。
我们将深入探讨async/await C#的机制,研究这种范式转变如何将慢速同步编程转变为高吞吐量的异步操作,并将这些关键概念与Iron Software如何帮助企业实现最佳性能联系起来。
异步编程基础
在async和await之前,异步操作是通过繁琐的回调和手动任务类操作来管理的,导致代码复杂且容易出错。 通过使开发人员能够编写看起来像是同步代码但行为表现为异步的代码,C#中的异步编程简化了这一点。
两个核心组成部分是
1.async 关键字:async 修饰符将方法标记为可包含 await 表达式的 async 方法。 最重要的是,将方法标记为异步并不会**自动在后台线程上运行。 它仅仅是让编译器生成一个复杂的状态机来管理代码的延续过程。 异步方法通常返回一个Task对象(Task或Task)来表示正在进行的异步任务。
2.await关键字:await关键字是一个神奇的组件。 当遇到 await 表达式时,该方法会检查等待的任务是否已完成。 如果没有,方法立即暂停执行,并将控制权交回给调用方法(或调用者)。 这将释放当前线程(通常是主线程或线程池线程)以处理其他请求或其他任务。 任务完成后,方法的剩余部分会被注册为继续,并重新安排运行时间。
下面是一个基础代码示例:
public static async Task<string> DownloadDataAsync(string url)
{
// The async keyword allows us to use await
using var client = new HttpClient();
// await task: Control returns to the caller while the HTTP call happens
string data = await client.GetStringAsync(url); // I/O-bound
// The code after the await expression runs once the task finishes
return $"Data length: {data.Length}";
}
// Modern entry point for console apps
public static async Task Main(string[] args)
{
// This is the static async task main entry point
var result = await DownloadDataAsync("https://api.example.com/data");
Console.WriteLine(result);
}Public Shared Async Function DownloadDataAsync(url As String) As Task(Of String)
' The async keyword allows us to use await
Using client As New HttpClient()
' await task: Control returns to the caller while the HTTP call happens
Dim data As String = Await client.GetStringAsync(url) ' I/O-bound
' The code after the await expression runs once the task finishes
Return $"Data length: {data.Length}"
End Using
End Function
' Modern entry point for console apps
Public Shared Async Function Main(args As String()) As Task
' This is the static async task main entry point
Dim result As String = Await DownloadDataAsync("https://api.example.com/data")
Console.WriteLine(result)
End FunctionPublic Shared Async Function DownloadDataAsync(url As String) As Task(Of String)
' The async keyword allows us to use await
Using client As New HttpClient()
' await task: Control returns to the caller while the HTTP call happens
Dim data As String = Await client.GetStringAsync(url) ' I/O-bound
' The code after the await expression runs once the task finishes
Return $"Data length: {data.Length}"
End Using
End Function
' Modern entry point for console apps
Public Shared Async Function Main(args As String()) As Task
' This is the static async task main entry point
Dim result As String = Await DownloadDataAsync("https://api.example.com/data")
Console.WriteLine(result)
End Function使用静态异步任务 main 是现代标准,无需使用 .Wait() 或 .Result 等传统方法阻塞主线程。
性能与 Iron 软件集成
虽然Task是异步代码的标准返回类型,但在.NET 10中,高级异步编程通常使用ValueTask来显著提高"热路径"中的性能,这些路径很有可能同步完成(例如,检索缓存值)。 ValueTask 可避免内存分配,因此对高吞吐量应用程序至关重要。
将异步操作应用于 Iron 软件
Iron Software的产品,如IronOCR(光学字符识别)和IronPDF(PDF生成),是利用异步调用的完美候选者。 将大型HTML文档转化为PDF或扫描数百页的图像进行文本识别这样的操作通常是受CPU限制的任务或涉及文件系统I/O,能从异步方法中获得巨大收益。
当您使用 Iron Software 提供的同步和异步方法时,就能确保您的应用程序保持高度响应。
考虑使用IronPDF从指定的URL创建文档:
public static async Task GeneratePdfFromUrlAsync(string url, string outputFileName)
{
// 1. Initialize the renderer
var renderer = new IronPdf.ChromePdfRenderer();
// Optional: Set rendering options if needed (e.g., margins, headers)
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
// 2. The core asynchronous operation: Fetch and render the URL content
// This is an I/O-bound task that releases the calling thread.
var pdf = await renderer.RenderUrlAsPdfAsync(url);
// 3. Save the PDF file asynchronously
await Task.Run(() =>
{
// This is the synchronous method you confirmed exists
pdf.SaveAs(outputFileName);
});
}public static async Task GeneratePdfFromUrlAsync(string url, string outputFileName)
{
// 1. Initialize the renderer
var renderer = new IronPdf.ChromePdfRenderer();
// Optional: Set rendering options if needed (e.g., margins, headers)
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
// 2. The core asynchronous operation: Fetch and render the URL content
// This is an I/O-bound task that releases the calling thread.
var pdf = await renderer.RenderUrlAsPdfAsync(url);
// 3. Save the PDF file asynchronously
await Task.Run(() =>
{
// This is the synchronous method you confirmed exists
pdf.SaveAs(outputFileName);
});
}Imports System.Threading.Tasks
Imports IronPdf
Public Module PdfGenerator
Public Async Function GeneratePdfFromUrlAsync(url As String, outputFileName As String) As Task
' 1. Initialize the renderer
Dim renderer As New ChromePdfRenderer()
' Optional: Set rendering options if needed (e.g., margins, headers)
renderer.RenderingOptions.PaperSize = Rendering.PdfPaperSize.A4
' 2. The core asynchronous operation: Fetch and render the URL content
' This is an I/O-bound task that releases the calling thread.
Dim pdf = Await renderer.RenderUrlAsPdfAsync(url)
' 3. Save the PDF file asynchronously
Await Task.Run(Sub()
' This is the synchronous method you confirmed exists
pdf.SaveAs(outputFileName)
End Sub)
End Function
End ModuleImports System.Threading.Tasks
Imports IronPdf
Public Module PdfGenerator
Public Async Function GeneratePdfFromUrlAsync(url As String, outputFileName As String) As Task
' 1. Initialize the renderer
Dim renderer As New ChromePdfRenderer()
' Optional: Set rendering options if needed (e.g., margins, headers)
renderer.RenderingOptions.PaperSize = Rendering.PdfPaperSize.A4
' 2. The core asynchronous operation: Fetch and render the URL content
' This is an I/O-bound task that releases the calling thread.
Dim pdf = Await renderer.RenderUrlAsPdfAsync(url)
' 3. Save the PDF file asynchronously
Await Task.Run(Sub()
' This is the synchronous method you confirmed exists
pdf.SaveAs(outputFileName)
End Sub)
End Function
End Module使用异步方法生成 PDF.

通过使用 RenderHtmlAsPdfAsync() 异步方法,我们可以防止应用程序在处理大型文档时冻结或阻塞。 本书演示了如何高效地编写异步代码以进行复杂的处理。
最佳实践和边缘案例
1.处理多个任务和 I/O.
为了最大限度地提高效率,在等待独立的 I/O 绑定工作(如从远程服务器获取数据或执行数据库查询)时,应同时启动多个任务。
public async Task<string[]> FetchAllDataAsync(string url1, string url2)
{
// Creating tasks starts the async operation immediately
Task<string> taskA = DownloadDataAsync(url1);
Task<string> taskB = DownloadDataAsync(url2);
// Wait for all the tasks to complete simultaneously
string[] results = await Task.WhenAll(taskA, taskB);
return results;
}public async Task<string[]> FetchAllDataAsync(string url1, string url2)
{
// Creating tasks starts the async operation immediately
Task<string> taskA = DownloadDataAsync(url1);
Task<string> taskB = DownloadDataAsync(url2);
// Wait for all the tasks to complete simultaneously
string[] results = await Task.WhenAll(taskA, taskB);
return results;
}Option Strict On
Option Infer On
Public Async Function FetchAllDataAsync(url1 As String, url2 As String) As Task(Of String())
' Creating tasks starts the async operation immediately
Dim taskA As Task(Of String) = DownloadDataAsync(url1)
Dim taskB As Task(Of String) = DownloadDataAsync(url2)
' Wait for all the tasks to complete simultaneously
Dim results As String() = Await Task.WhenAll(taskA, taskB)
Return results
End FunctionOption Strict On
Option Infer On
Public Async Function FetchAllDataAsync(url1 As String, url2 As String) As Task(Of String())
' Creating tasks starts the async operation immediately
Dim taskA As Task(Of String) = DownloadDataAsync(url1)
Dim taskB As Task(Of String) = DownloadDataAsync(url2)
' Wait for all the tasks to complete simultaneously
Dim results As String() = Await Task.WhenAll(taskA, taskB)
Return results
End Function这是一种标准模式,用于创建并发运行的任务,通过利用非阻塞异步操作大大加快应用程序的响应时间。
2.同步上下文和配置等待(false)
当等待的任务完成时,默认行为是捕获同步上下文并确保在同一线程(如用户界面线程)上继续运行。 这对用户界面应用程序至关重要,但会给服务器端或库代码带来不必要的开销。 using ConfigureAwait(false) 可以告诉运行时,await 调用后的代码可以在任何可用的线程池后台线程上继续运行。 对于库开发人员来说,这是一个至关重要的实践,可以确保异步操作的最高性能:
// Critical for shared libraries to avoid deadlocks and improve throughput
var data = await GetVarDataFromRemoteServer().ConfigureAwait(false);
// This code continues on any thread, improving resource usage.// Critical for shared libraries to avoid deadlocks and improve throughput
var data = await GetVarDataFromRemoteServer().ConfigureAwait(false);
// This code continues on any thread, improving resource usage.' Critical for shared libraries to avoid deadlocks and improve throughput
Dim data = Await GetVarDataFromRemoteServer().ConfigureAwait(False)
' This code continues on any thread, improving resource usage.' Critical for shared libraries to avoid deadlocks and improve throughput
Dim data = Await GetVarDataFromRemoteServer().ConfigureAwait(False)
' This code continues on any thread, improving resource usage.3.async void 的危险
异步编程中最重要的规则之一是,除了异步事件处理程序外,永远不要使用异步 void。 例如,按钮点击事件处理方法通常使用 async void:
private async void Button_Click(object sender, EventArgs e) // event handler
{
// This is one of the few places async void is acceptable
await GenerateReportAsync(html);
}private async void Button_Click(object sender, EventArgs e) // event handler
{
// This is one of the few places async void is acceptable
await GenerateReportAsync(html);
}Private Async Sub Button_Click(sender As Object, e As EventArgs) Handles Button.Click ' event handler
' This is one of the few places async void is acceptable
Await GenerateReportAsync(html)
End SubPrivate Async Sub Button_Click(sender As Object, e As EventArgs) Handles Button.Click ' event handler
' This is one of the few places async void is acceptable
Await GenerateReportAsync(html)
End Sub强烈反对使用任何其他异步 void 方法。 由于async void方法无法被等待,调用线程无法跟踪其完成或可靠地处理异常,使错误处理变得棘手。 对于所有其他异步方法,总是返回Task或Task。
4.异常处理
稳健的异常处理至关重要。 当异步操作失败时(如网络服务调用遇到错误),异常会存储在任务对象中。 在等待任务时,await 表达式会将异常重新抛给当前线程(继续执行任务的线程),从而使标准 try...catch 块能够有效地处理异常。
结论
C# 中的 async 和 await 模式是一种模式转换功能,它使开发人员从脆性同步编程转向弹性、可扩展的异步方法。 通过理解底层状态机并遵循最佳实践——例如优先选择Task而不是async void,在库中使用ConfigureAwait(false),以及正确实现异常处理——开发人员可以创建能够以卓越性能处理复杂处理任务的应用程序(如Iron Software套件中的那些)。
Iron Software 致力于开发以高性能异步编程为核心的产品,确保您的代码编写实践能够带来最大的吞吐量。 探索Iron Software的世界,看看利用异步任务处理如何能显著提升您应用程序的速度和响应能力。