首页 > 编程语言 >C#中如何使用异步编程

C#中如何使用异步编程

时间:2025-01-07 18:58:14浏览次数:7  
标签:异步 Task string C# 编程 using async await

在 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);
}
  1. 避免阻塞异步代码:
    • 不要使用 .Result.Wait() 来阻塞异步任务,这可能导致死锁。
    • 始终使用 await 来等待异步任务。
  2. 性能优化:
    * • 对于高性能场景,可以使用 ValueTask 代替 Task

6. 异步编程的好处

  1. . 提高响应性:
    • • 异步操作不会阻塞主线程,使得应用程序在等待耗时操作时保持响应。
  2. . 提高资源利用率:
    • • 异步操作可以更高效地利用系统资源,特别是在 I/O 密集型操作中。
  3. . 简化代码:
    • • 使用 asyncawait 可以使异步代码的结构更加清晰,易于理解和维护。

总结

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

标签:异步,Task,string,C#,编程,using,async,await
From: https://www.cnblogs.com/liyongqiang-cc/p/18658141

相关文章

  • react项目性能优化实践经验总结
    1.代码片段执行时间console.time('xxx')//代码片段console.timeEnd('xxx')在代码片段包裹上述代码,执行后,命令行会输出该段代码的执行时间,非常方便。2.reactProfilereact的<Profiler/>包裹组件后,并传入id和onRender回调函数。id是一个唯一标识符,用于区分不同的Profiler......
  • CSP -J 考前复习一文通
    前言本文算是作者的学习笔记,也可以用于CSP-J初赛考前复习,如有错误请在评论指出。本文写作时间比较紧张,参考了各种资料,包括但不限于百度百科、OI-wiki、洛谷专栏、各类参考书籍等等,在此一并感谢。如有侵权,请联系删除或更换。本文同步发表于:博客园:https://www.cnblogs.com/ny......
  • P4175 [CTSC2008] 网络管理
    P4175[CTSC2008]网络管理Solution:存了半年,骂了半年的树上树套树还是在今天咬着牙写完了真是可恶首先我们来回顾一下如果不带修的话这题怎么做:对每个点维护一颗主席树,存rt->u这条路径上的边的权值。然后对于一个查询(x,y,k)在x+y-lca-fa[lca]这颗树上查第k大值.那么我......
  • P2617 Dynamic Rankings
    P2617DynamicRankings题目描述给定一个含有\(n\)个数的序列\(a_1,a_2\dotsa_n\),需要支持两种操作:Qlrk表示查询下标在区间\([l,r]\)中的第\(k\)小的数Cxy表示将\(a_x\)改为\(y\)【数据范围】对于\(100\%\)的数据,\(1\len,m\le10^5\),\(1\lel\le......
  • docker启动nacos报错: Nacos Server did not start because dumpservice bean constru
    一、docker启动nacos报错:mysql版本:8nacos版本:2.xNacosServerdidnotstartbecausedumpservicebeanconstructionfailure:NoDataSourcesetNacosisstarting,youcandockerlogsyourcontainer+exec/opt/java/openjdk/bin/java-XX:+UseConcMarkSweepGC-XX:+U......
  • P2894 [USACO08FEB] Hotel G && P3071 [USACO13JAN] Seating G
    P2894[USACO08FEB]HotelGP3071[USACO13JAN]SeatingG题目描述第一行输入\(n,m\),\(n\)代表有\(n\)个房间\((1\leqn\leq50,000)\),编号为\(1\simn\),开始都为空房,\(m\)表示以下有\(m\)行操作\((1\leqm<50,000)\),以下每行先输入一个数\(i\),表示一种操作:若......
  • Vector的一些用法
    Vector常见用法Vector与静态数组的区别:相同点:(1)vector和静态数组都只能对同一类型的数据进行储存。(2)两者储存是连续的,可也进行随机访问。(3)都可用下标进行处理。不同点:(1)vector的长度一般不固定,可以根据数据的插入和删除重新构造容器容量,数据的而数组的长度已经固定,因此v......
  • 剑指Offer|LCR 023. 相交链表
    LCR023.相交链表给定两个单链表的头节点headA和headB,请找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回null。图示两个链表在节点c1开始相交**:**题目数据保证整个链式结构中不存在环。注意,函数返回结果后,链表必须保持其原始结构。示例1......
  • MQTT和传统消息队列(RabbitMQ,RocketMQ,Kafka)的区别
    适用场景选择哪种协议取决于具体的应用需求。如果需要适用于大量传感器和控制设备之间的通信,且网络环境不稳定或需要节省带宽资源,MQTT是一个不错的选择。而如果需要在浏览器和服务端之间建立实时双向通信,且对实时性和双向交互有较高要求,WebSocket可能更加适合。   产......
  • 传输层重点协议(TCP协议)深度解剖
    传输控制协议(TCP,TransmissionControlProtocol)是传输层中最重要的协议之一。它提供可靠的、面向连接的通信服务,确保数据在网络中准确传输。以下是对TCP协议的深度解剖。TCP协议概述TCP协议的设计目标是提供可靠的数据传输服务。它通过建立连接、数据分段、流量控制、拥塞控制和......