C#中如何使用异步编程

ops/2025/1/20 3:28:03/

在 C# 中,异步编程主要通过 async 和 await 关键字来实现。异步编程的目的是让程序在执行耗时操作(如 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、简化代码:

• 使用 async 和 await 可以使异步代码的结构更加清晰,易于理解和维护。

总结

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

文章转载自:代码拾光

原文链接:C#中如何使用异步编程 - 代码拾光 - 博客园

体验地址:引迈 - JNPF快速开发平台_低代码开发平台_零代码开发平台_流程设计器_表单引擎_工作流引擎_软件架构


http://www.ppmy.cn/ops/151549.html

相关文章

虚幻基础2:gameplay框架

能帮到你的话&#xff0c;就给个赞吧 &#x1f618; 文章目录 ue框架&#xff1a;gameplay组成game modeactorcomponent player controllergame state 工作流程 ue框架&#xff1a;gameplay 组成 game mode 游戏类型和规则。可以控制游戏的开始与结束以及一些其他功能。 ac…

AI 编程工具—Cursor 对话模式详解 Chat、Composer 与 Normal/Agent 模式

Cursor AI 对话模式详解:Chat、Composer 与 Normal/Agent 模式 一、简介 Cursor 是一个强大的 AI 辅助编程工具,它提供了多种对话模式来满足不同的开发需求。主要包括: Chat 模式:直接对话交互Composer 模式:结构化编程助手Normal/Agent 模式:不同的 AI 响应策略打开Ch…

InVideo AI技术浅析(二):自然语言处理

InVideo AI的自然语言处理(NLP)模块是整个系统中的关键部分,负责处理和分析用户输入的文本数据,以实现智能化的视频生成和编辑功能。 1. 文本解析与理解 1.1 文本解析过程 文本解析是将用户输入的自然语言文本转换为机器可理解的格式的过程。解析过程可以分为以下几个步…

软考信安25~移动应用安全需求分析与安全保护工程

1、移动应用安全威胁与需求分析 1.1、移动应用系统组成 包括三个部分: 一是移动应用,简称App; 二是通信网络,包括无线网络、移动通信网络及互联网; 三是应用服务端,由相关的服务器构成,负责处理来自App 的相关信息或数据。 1.2、移动应用安全分析 (1)移动操作系统平…

2.3.1(项目)kv存储——框架梳理(待定)

一、过一遍代码路线&#xff1a; &#xff08;1&#xff09;底层网络框架&#xff1b;&#xff08;2&#xff09;业务层的协议设计(发什么数据&#xff0c;以及收什么数据)&#xff1b;&#xff08;3&#xff09;业务层的引擎设计&#xff1b; 1. 底层网络框架&#xff1a; …

游戏引擎学习第81天

仓库:https://gitee.com/mrxiao_com/2d_game_2 或许我们应该尝试在地面上添加一些绘图 在这段时间的工作中&#xff0c;讨论了如何改进地面渲染的问题。虽然之前并没有专注于渲染部分&#xff0c;因为当时主要的工作重心不在这里&#xff0c;但在实现过程中&#xff0c;发现地…

Golang笔记——包的循环引用问题(import cycle not allowed)和匿名导入

大家好&#xff0c;这里是Good Note&#xff0c;关注 公主号&#xff1a;Goodnote&#xff0c;专栏文章私信限时Free。本文详细介绍Golang中包的循环引用问题(import cycle not allowed)和匿名导入问题。 文章目录 循环引用问题优势设计原因解决方法 明确导入的包必须使用匿名导…

“大数据+技校”:VR虚拟仿真实训室的发展前景

在技术教育的新时代&#xff0c;大数据与虚拟现实技术的融合正在重塑技校的教学模式。"大数据技校"模式下的VR虚拟仿真实训室&#xff0c;为技校学生提供了一个创新的学习平台&#xff0c;预示着教育方式的深刻变革。 一、大数据与技校教育的深度融合 大数据技术的应…