在 C# 中,异步编程主要通过 async 和 await 关键字来实现。异步编程的目的是让程序在执行耗时操作(如 I/O 操作、网络请求等)时不会阻塞主线程,从而提高程序的性能。
1. 异步编程的核心概念
async 关键字
用于标记一个方法为异步方法。
异步方法的返回类型通常是 Task、Task<T> 或 ValueTask。
Task:表示一个没有返回值的异步操作。
Task<T>:表示一个返回类型为 T 的异步操作。
ValueTask:轻量版的 Task,适用于高性能场景。
await 关键字
2. 异步编程的基本语法
定义异步方法
 public async Task GetDataAsync(){    // 异步操作    await Task.Delay(1000); // 模拟耗时操作}
       复制代码
 
调用异步方法
 public async Task CallAsyncMethod(){    await GetDataAsync(); // 等待异步方法完成    Console.WriteLine("异步方法已调用.");}
       复制代码
 
3. 异步编程的使用场景
I/O 密集型操作
UI 应用程序
Web 应用程序
并行任务
4. 异步编程的示例
1:简单的异步方法
 using System;using System.Threading.Tasks;
class Program{    static async Task Main(string[] args)    {        Console.WriteLine("开始异步操作...");        await DoSomethingAsync();        Console.WriteLine("异步操作已完成.");    }
    static async Task DoSomethingAsync()    {        await Task.Delay(2000); // 模拟耗时操作(2秒)        Console.WriteLine("DoSomethingAsync方法异步任务已完成.");    }}
       复制代码
 
输出:
 开始异步操作...DoSomethingAsync方法异步任务已完成.异步操作已完成.
       复制代码
 
2:异步文件读写
 using System;using System.IO;using System.Threading.Tasks;
class Program{    static async Task Main(string[] args)    {        string filePath = "task-test.txt";        string content = "hello async";
        // 异步写入文件        await WriteFileAsync(filePath, content);        Console.WriteLine("文件已写入");
        // 异步读取文件        string readContent = await ReadFileAsync(filePath);        Console.WriteLine("文件内容: " + readContent);    }
    static async Task WriteFileAsync(string filePath, string content)    {        await File.WriteAllTextAsync(filePath, content);    }
    static async Task<string> ReadFileAsync(string filePath)    {        return await File.ReadAllTextAsync(filePath);    }}
       复制代码
 
输出:
3:异步网络请求
 using System;using System.Net.Http;using System.Threading.Tasks;
class Program{    static async Task Main(string[] args)    {        string url = "https://xxxxx.com";        string content = await DownloadContentAsync(url);        Console.WriteLine("Content: " + content);    }
    static async Task<string> DownloadContentAsync(string url)    {        using (HttpClient client = new HttpClient())        {            return await client.GetStringAsync(url);        }    }}
       复制代码
 
4:并行异步任务
 using System;using System.Net.Http;using System.Threading.Tasks;
class Program{    static async Task Main(string[] args)    {        Task<string> task1 = DownloadContentAsync("https://xxx.com");        Task<string> task2 = DownloadContentAsync("https://xxx2.com");
        string[] results = await Task.WhenAll(task1, task2);        Console.WriteLine("Task 1 result: " + results[0]);        Console.WriteLine("Task 2 result: " + results[1]);    }
    static async Task<string> DownloadContentAsync(string url)    {        using (HttpClient client = new HttpClient())        {            return await client.GetStringAsync(url);        }    }}
       复制代码
 
5. 异步编程的注意事项
1、避免 async void:
• 除了事件处理程序外,尽量避免使用 async void 方法,因为它无法被等待,且异常无法被捕获。
2、正确处理异常:
• 使用 try-catch 块来捕获异步方法中的异常。
 try{    await GetDataAsync();}catch (Exception ex){    Console.WriteLine("Error: " + ex.Message);}
       复制代码
 
3、避免阻塞异步代码:
• 不要使用 .Result 或 .Wait() 来阻塞异步任务,这可能导致死锁。
• 始终使用 await 来等待异步任务。
4、性能优化:
• 对于高性能场景,可以使用 ValueTask 代替 Task。
6. 异步编程的好处
1、提高响应性:
• 异步操作不会阻塞主线程,使得应用程序在等待耗时操作时保持响应。
2、提高资源利用率:
• 异步操作可以更高效地利用系统资源,特别是在 I/O 密集型操作中。
3、简化代码:
• 使用 async 和 await 可以使异步代码的结构更加清晰,易于理解和维护。
总结
C# 中的异步编程通过 async 和 await 关键字实现,能够显著提高程序的响应性和性能。它特别适用于 I/O 密集型操作、UI 应用程序和 Web 应用程序等场景。通过合理使用异步编程,可以编写出高效、简洁且易于维护的代码。
文章转载自:代码拾光
原文链接:https://www.cnblogs.com/liyongqiang-cc/p/18658141
体验地址:http://www.jnpfsoft.com/?from=001YH
评论