C#中如何使用异步编程

在 C# 中,异步编程主要通过 asyncawait 关键字来实现。异步编程的目的是让程序在执行耗时操作(如 I/O 操作、网络请求等)时不会阻塞主线程,从而提高程序的性能。

1. 异步编程的核心概念

async 关键字

  • 用于标记一个方法为异步方法。
  • 异步方法的返回类型通常是 TaskTask<T>ValueTask
    Task:表示一个没有返回值的异步操作。
    Task<T>:表示一个返回类型为 T 的异步操作。
    ValueTask:轻量版的 Task,适用于高性能场景。

await 关键字

  • 用于暂停异步方法的执行,直到等待的任务完成。
  • await 只能用于 async 方法中。
  • 它不会阻塞线程,而是将控制权交回给调用方,直到任务完成后再恢复执行。

2. 异步编程的基本语法

定义异步方法

public async Task GetDataAsync()
{
    // 异步操作
    await Task.Delay(1000); // 模拟耗时操作
}

调用异步方法

public async Task CallAsyncMethod()
{
    await GetDataAsync(); // 等待异步方法完成
    Console.WriteLine("异步方法已调用.");
}

3. 异步编程的使用场景

I/O 密集型操作

  • 文件读写、数据库查询、网络请求等操作通常需要较长时间,使用异步编程可以避免阻塞主线程。

UI 应用程序

  • 在桌面或移动应用程序中,保持 UI 线程的响应性极为重要。异步操作可以防止 UI 卡顿,提升用户体验。

Web 应用程序

  • ASP.NET 等 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);
    }
}

输出:

文件已写入
文件内容: hello async

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. . 简化代码:
    • • 使用 asyncawait 可以使异步代码的结构更加清晰,易于理解和维护。

总结

C# 中的异步编程通过 asyncawait 关键字实现,能够显著提高程序的响应性和性能。它特别适用于 I/O 密集型操作、UI 应用程序和 Web 应用程序等场景。通过合理使用异步编程,可以编写出高效、简洁且易于维护的代码。

相关推荐
代码拾光2 天前
在 ASP.NET Core WebAPI如何实现版本控制?
.net core
下一秒_待续2 天前
.Net8 Avalonia跨平台UI框架——<vlc:VideoView>控件播放海康监控、摄像机视频(Windows / Linux)
跨平台·.net core·avalonia
代码拾光3 天前
如何在 ASP.NET Core 中实现速率限制?
.net core
代码拾光4 天前
.NET Core 委托原理解析
.net core
代码拾光6 天前
中间件 vs 过滤器
.net core
代码拾光7 天前
了解 ASP.NET Core 中的中间件
.net core
petunsecn7 天前
EFCore HasDefaultValueSql
c#·.net core
代码拾光7 天前
.NetCore依赖注入(DI)之生命周期
.net core
Damon小智8 天前
C#进阶-在Ubuntu上部署ASP.NET Core Web API应用
linux·nginx·c#·asp.net·.net·.net core