C# --- 异步编程(Async/Await)

异步编程使程序能够在等待长时间运行的任务时保持响应性。C# 使用 async 和 await 关键字来简化异步编程。

目录

6.1 基本概念

> 1 async

> 2 await

> 3 Task

> 4 Task.Run

> 5 Task.WhenAll

> 6 Task.WhenAny

> 7 Task.Delay

> 8 Task.FromResult

> 9 Task.CompletedTask

> 10 Task.Factory.StartNew


6.1 基本概念

> async 关键字:标记方法为异步方法。

> await 关键字:等待异步操作完成。

异步编程(Async/Await)就像在餐厅点菜:

> 普通编程:你点了菜后就一直等待,不做其他事情,直到菜做好才能继续。

> 异步编程:你点了菜后可以去做其他事情,比如聊天或看电视,等菜做好了再去取。这样你就能高效地利用时间,不浪费等待的过程。

6.1.1 示例:基本异步方法

using System;
using System.Threading.Tasks;

//---
class Program
{
    static async Task Main(string[] args)
    {
        await DoSomethingAsync();
        Console.WriteLine(13213131231313);
        Console.WriteLine("Async method completed.");
    }

    //---
    static async Task DoSomethingAsync()
    {
        await Task.Delay(2000); // 模拟异步操作
        Console.WriteLine("Something was done.");
    }
}

6.1.2 示例:返回值的异步方法

using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        int result = await CalculateSumAsync(5, 10);
        Console.WriteLine($"Result: {result}");
    }

    static async Task<int> CalculateSumAsync(int a, int b)
    {
        await Task.Delay(1000); //模拟异步操作
        return a + b;
    }
}

6.1.3 异步方法中的异常处理

using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        try
        {
            int result = await CalculateSumAsync(5, 10);
            Console.WriteLine($"Result: {result}");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Exception: {ex.Message}");
        }
    }

    //---
    static async Task<int> CalculateSumAsync(int a, int b)
    {
        await Task.Delay(1000); // 模拟异步操作
        throw new InvalidOperationException("An error occurred during the calculation.");
        return a + b;
    }
}

6.1.4 并行执行多个异步操作

using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        Task<int> task1 = CalculateSumAsync(5, 10);
        Task<int> task2 = CalculateSumAsync(20, 30);

        int[] results = await Task.WhenAll(task1, task2);

        Console.WriteLine($"Result 1: {results[0]}");
        Console.WriteLine($"Result 2: {results[1]}");
    }

    static async Task<int> CalculateSumAsync(int a, int b)
    {
        await Task.Delay(1000); // 模拟异步操作
        return a + b;
    }
}


using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        // 启动异步数据加载
        Task<int> dataTask = LoadDataAsync();

        // 执行其他任务
        for (int i = 0; i < 10; i++)
        {
            Console.WriteLine($"Processing other tasks: {i + 1}/10");
            await Task.Delay(500); // 模拟其他任务的工作
        }

        // 直接访问 dataTask 结果(不使用 await)
        // 这可能会导致获取到尚未完成的任务的结果
        int result = dataTask.Result;
        Console.WriteLine($"Data loaded: {result}");
    }

    static async Task<int> LoadDataAsync()
    {
        Console.WriteLine("Loading data...");
        await Task.Delay(3000); // 模拟网络延迟,假设数据加载需要 3 秒钟
        return 42; // 模拟返回的数据
    }

}

6.1.5 小结

> async:用于定义异步方法。

> await:用于等待异步操作完成。

> 返回值:异步方法可以返回 Task 或 Task<T>。

> 1 无返回值的任务:

    Task.Run(() => {

        // 执行一些异步操作

        Console.WriteLine("Task completed.");

    });

> 2 有返回值的任务:

    Task<int> task = Task.Run(() => {

        // 执行一些异步操作并返回结果

        return 42;

    });

    int result = await task; // 使用 await 获取结果

    Console.WriteLine($"Result: {result}");

> 异常处理:使用 try-catch 来处理异步操作中的异常。

> 并行执行:使用 Task.WhenAll 并行执行多个异步操作。

> 1 async

> 解释

> 1.1 用于标记一个方法为异步方法,表示该方法可以包含 await 表达式。

> 1.2 异步方法必须返回 Task、Task<TResult> 或 void(虽然不推荐使用 void)。

> 1.3 例如:

    async Task<int> CalculateSumAsync(int a, int b)

    {

        return a + b;

    }

> 2 await

> 解释

> 1.1 用于等待异步操作完成,并获取其结果。

> 1.2 只能在标记为 async 的方法中使用。

> 1.3 例如:

    int result = await CalculateSumAsync(5, 10);

> 3 Task

> 解释

> 1.1 表示一个异步操作,Task 是无返回值的,Task<TResult> 是有返回值的。

> 1.2 可以通过 Task 对象的 Result 属性获取结果(但通常不推荐,因为它可能会阻塞线程)。

> 4 Task.Run

> 解释

> 1.1 用于启动一个新的异步操作,将其安排在线程池中执行。

> 1.2 例如:

    Task.Run(() => {

        // 执行一些异步操作

    });

> 5 Task.WhenAll

> 解释

> 1.1 用于等待异步操作完成,并获取其结果。

> 1.2 例如:

    await Task.WhenAll(task1, task2, task3);

> 6 Task.WhenAny

> 解释

> 1.1 用于等待一组异步操作中任意一个完成,并返回一个 Task,该任务在其中一个任务完成时完成。

> 1.2 例如:

    Task completedTask = await Task.WhenAny(task1, task2, task3);

> 7 Task.Delay

> 解释

> 1.1 用于创建一个延迟的异步任务,通常用于模拟等待时间或延迟操作。

> 1.2 例如:

    await Task.Delay(1000); // 延迟 1 秒

> 8 Task.FromResult

> 解释

> 1.1 用于创建一个已完成的 Task,并返回指定的结果。

> 1.2 例如:

    Task<int> completedTask = Task.FromResult(42);

> 9 Task.CompletedTask

> 解释

> 1.1 用于获取一个已完成的 Task 对象,通常用于没有返回值的异步操作。

> 1.2 例如:

    Task completedTask = Task.CompletedTask;

> 10 Task.Factory.StartNew

> 解释

> 1.1 用于创建并启动一个任务,这个方法提供了更多的配置选项,但在大多数情况下,使用 Task.Run 更为常见。

> 1.2 例如:

    Task task = Task.Factory.StartNew(() => {

        // 执行某些工作

    });

  • 9
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

颜回.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值