C# 异步调用aysnc await

news/2024/12/2 22:32:21/

一、基本概念

在C#中,async和await关键字用于异步编程。异步编程允许程序在执行I/O密集型操作时不会被阻塞,从而提高程序的性能和响应性。

async关键字用于定义异步方法,表明该方法可能包含await表达式,并且可以在其执行期间异步等待其他操作的完成。
await关键字用于等待异步操作完成,它只能在async方法内使用。await表达式会挂起当前方法的执行,直到其等待的操作完成,然后恢复方法的执行。


二、使用方法调用的方式

代码如下(示例):

using System;
using System.Collections.Generic;
using System.Threading.Tasks;class Program
{static void Main(string[] args){// 调用 test 方法,该方法是异步的,但不会阻塞主线程test();Console.WriteLine("main end..."); // 输出主函数结束的提示Console.ReadKey(); // 等待用户输入任意键,保持程序运行}// 异步方法 teststatic async void test(){// 异步等待 2000 毫秒(2 秒)await Task.Delay(2000);// 调用 stest 方法创建三个异步任务Task<int> Result0 = stest(100, 2000);Task<int> Result1 = stest(200, 3000);Task<int> Result2 = stest(300, 4000);// 创建一个任务列表,将三个异步任务添加到列表中List<Task<int>> tsklst = new List<Task<int>>();tsklst.AddRange(new List<Task<int>> { Result0, Result1, Result2 });// 输出开始执行异步任务的提示Console.WriteLine("delegateFuncTaskReturn has been Started {0}", 100);// 使用 Task.WhenAny 方法异步等待任务列表中的任意一个任务完成Task<int> firstCompletedTask = await Task.WhenAny(tsklst);// 输出异步任务完成后的提示Console.WriteLine("after WhenAny");Console.WriteLine("firstCompletedTask has been done and returned value {0}", firstCompletedTask.Result);Console.WriteLine("program end"); // 输出程序结束的提示}// 异步方法 stest,接受一个整数参数 input 和一个整数参数 delaystatic async Task<int> stest(int input, int delay){// 异步等待指定的延迟时间await Task.Delay(delay);// 输出异步方法执行完成的提示,并打印输入值加 1 的结果Console.WriteLine("delegateFuncTaskReturn has been done and returned value {0}", input + 1);// 再次异步等待 1000 毫秒(1 秒)await Task.Delay(1000);// 返回输入值减去 1return input - 1;}
}

这段代码的主要逻辑是创建了三个异步任务(Result0Result1Result2),每个任务都会在一定的延迟后返回一个结果。然后,使用 Task.WhenAny 方法等待任意一个任务完成。在 test 方法中,还输出了一些提示信息以表示异步任务的启动和完成状态。

以下是代码的执行过程和输出结果的总结:

  1. 主函数 Main 开始执行,调用 test 方法。
  2. test 方法异步等待了 2000 毫秒(2 秒)。
  3. stest 方法被调用三次,每次传入不同的参数,并且每个方法内部会异步等待一定的延迟时间后返回结果。
  4. 输出了五次 “delegateFuncTaskReturn has been Started 100” 的提示信息,表示异步任务已经启动。
  5. 使用 Task.WhenAny 方法等待任意一个任务完成。
  6. 当第一个任务完成时,输出了 “after WhenAny” 的提示信息,并打印了第一个完成任务的结果。
  7. 最后输出 “program end” 表示程序执行结束。

因为 Task.WhenAny 方法会返回第一个完成的任务,所以输出结果可能会因为任务执行顺序不同而有所不同,但总体上,程序会在异步任务完成后输出相应的提示信息和结果。输出结果如下:

test start...
main end...
delegateFuncTaskReturn has been Started 100
delegateFuncTaskReturn has been done and returned value 101
after WhenAny
firstCompletedTask has been done and returned value 99
program end
delegateFuncTaskReturn has been done and returned value 201
delegateFuncTaskReturn has been done and returned value 301

三、使用lamda和异步委托的方式

代码如下(示例):

using System;
using System.Collections.Generic;
using System.Threading.Tasks;class Program
{static void Main(string[] args){Console.WriteLine("test2 start..."); // 输出测试开始的提示信息test2(); // 调用异步方法 test2Console.WriteLine("main end..."); // 输出主函数结束的提示信息Console.ReadKey(); // 等待用户输入任意键,保持程序运行}// 异步方法 test2static async void test2(){await Task.Delay(2000); // 异步等待 2000 毫秒(2 秒)// 使用 lambda 表达式定义异步委托 stestFunc<int, int, Task<int>> stest = async (int input, int delay) =>{await Task.Delay(delay); // 异步等待指定的延迟时间Console.WriteLine("delegateFuncTaskReturn has been done and returned value {0}", input + 1); // 输出异步方法执行完成的提示,并打印输入值加 1 的结果await Task.Delay(1000); // 再次异步等待 1000 毫秒(1 秒)return input - 1; // 返回输入值减去 1};// 创建三个异步任务,每个任务传入不同的参数Task<int> Result0 = stest(100, 2000);Task<int> Result1 = stest(200, 3000);Task<int> Result2 = stest(300, 4000);List<Task<int>> tsklst = new List<Task<int>>(); // 创建任务列表tsklst.AddRange(new List<Task<int>> { Result0, Result1, Result2 }); // 将三个异步任务添加到列表中Console.WriteLine("delegateFuncTaskReturn has been Started {0}", 100); // 输出异步任务已经启动的提示信息// 使用 Task.WhenAny 方法异步等待任务列表中的任意一个任务完成Task<int> firstCompletedTask = await Task.WhenAny(tsklst);Console.WriteLine("after WhenAny"); // 输出异步任务完成后的提示信息Console.WriteLine("firstCompletedTask has been done and returned value {0}", firstCompletedTask.Result); // 打印第一个完成任务的结果Console.WriteLine("program end"); // 输出程序结束的提示信息}
}

这段代码与之前的代码类似,不同之处在于 test2 方法中使用了 lambda 表达式来定义异步委托 stest,而不是单独定义一个异步方法 stest

以下是代码的执行过程和解释:

  1. 主函数 Main 开始执行,调用 test2 方法。
  2. test2 方法异步等待了 2000 毫秒(2 秒)。
  3. 使用 lambda 表达式定义了一个异步委托 stest,该委托接受两个参数 inputdelay,并在内部异步等待一定的延迟时间后返回一个结果。
  4. 使用 stest 异步委托创建了三个异步任务 Result0Result1Result2,每个任务传入不同的参数。
  5. 输出了五次 “delegateFuncTaskReturn has been Started 100” 的提示信息,表示异步任务已经启动。
  6. 使用 Task.WhenAny 方法等待任意一个任务完成。
  7. 当第一个任务完成时,输出了 “after WhenAny” 的提示信息,并打印了第一个完成任务的结果。
  8. 最后输出 “program end” 表示程序执行结束。

与之前的代码相比,这段代码的主要区别在于使用了 lambda 表达式来定义异步委托,使代码更加简洁和紧凑。代码主要利用了异步方法和异步委托来实现并行执行多个任务。主要执行步骤和注释已经在代码中说明。

test2 start...
main end...
delegateFuncTaskReturn has been Started 100
delegateFuncTaskReturn has been done and returned value 101
after WhenAny
firstCompletedTask has been done and returned value 99
program end
delegateFuncTaskReturn has been done and returned value 201
delegateFuncTaskReturn has been done and returned value 301

四、稍加修改变成阻塞方法

代码如下(示例):

 using System;
using System.Collections.Generic;
using System.Threading.Tasks;class Program
{static async Task Main(string[] args){Console.WriteLine("test2 start..."); // 输出测试开始的提示信息await test2(); // 异步调用 test2 方法,并等待其完成Console.WriteLine("main end..."); // 输出主函数结束的提示信息Console.ReadKey(); // 等待用户输入任意键,保持程序运行}// 异步方法 test2,返回一个 Task<int> 对象static async Task<int> test2(){await Task.Delay(2000); // 异步等待 2000 毫秒(2 秒)// 使用 lambda 表达式定义异步委托 stestFunc<int, int, Task<int>> stest = async (int input, int delay) =>{await Task.Delay(delay); // 异步等待指定的延迟时间Console.WriteLine("delegateFuncTaskReturn has been done and returned value {0}", input + 1); // 输出异步方法执行完成的提示,并打印输入值加 1 的结果await Task.Delay(1000); // 再次异步等待 1000 毫秒(1 秒)return input - 1; // 返回输入值减去 1};// 创建三个异步任务,每个任务传入不同的参数Task<int> Result0 = stest(100, 2000);Task<int> Result1 = stest(200, 3000);Task<int> Result2 = stest(300, 4000);List<Task<int>> tsklst = new List<Task<int>>(); // 创建任务列表tsklst.AddRange(new List<Task<int>> { Result0, Result1, Result2 }); // 将三个异步任务添加到列表中Console.WriteLine("delegateFuncTaskReturn has been Started"); // 输出异步任务已经启动的提示信息// 使用 Task.WhenAny 方法异步等待任务列表中的任意一个任务完成Task<int> firstCompletedTask = await Task.WhenAny(tsklst);Console.WriteLine("after WhenAny"); // 输出异步任务完成后的提示信息Console.WriteLine("firstCompletedTask has been done and returned value {0}", firstCompletedTask.Result); // 打印第一个完成任务的结果Console.WriteLine("program end"); // 输出程序结束的提示信息return 0; // 返回 0,表示方法执行完成}
}

这段代码利用了异步方法和异步委托来实现并行执行多个任务,并且在 Main 方法中也使用了异步特性。主要执行步骤和注释已经在代码中说明。增加await关键字使它变成阻塞的方法。
输出结果如下:

test2 start...
delegateFuncTaskReturn has been Started
delegateFuncTaskReturn has been done and returned value 101
after WhenAny
firstCompletedTask has been done and returned value 99
program end
main end...
delegateFuncTaskReturn has been done and returned value 201
delegateFuncTaskReturn has been done and returned value 301

http://www.ppmy.cn/news/1381007.html

相关文章

内存卡格式化危机:数据恢复之道与预防之策

在我们的日常生活和工作中&#xff0c;内存卡作为一种便携的存储介质&#xff0c;扮演着不可或缺的角色。然而&#xff0c;有时我们可能会遭遇一个令人头痛的问题——内存卡格式化了。这意味着原本存储在卡内的照片、视频、文档等重要数据&#xff0c;突然之间消失得无影无踪。…

linux内建命令/内部命令之exec

1.exec介绍 exec是linux shell内建命令&#xff0c;该命令将使用一个特定的命令来取代当前进程。一般当shell遇到一个命令&#xff0c;它会forks off一个子进程来真正的运行命令&#xff0c;但使用exec内建命令&#xff0c;shell就不会fork一个子进程了&#xff0c;并且命令的…

多维时序 | Matlab实现VMD-CNN-BiLSTM变分模态分解结合卷积神经网络结合双向长短期记忆神经网络多变量时间序列预测

多维时序 | Matlab实现VMD-CNN-BiLSTM变分模态分解结合卷积神经网络结合双向长短期记忆神经网络多变量时间序列预测 目录 多维时序 | Matlab实现VMD-CNN-BiLSTM变分模态分解结合卷积神经网络结合双向长短期记忆神经网络多变量时间序列预测预测效果基本介绍程序设计参考资料 预测…

0008、ts的类型推论

TypeScript的类型推论是指在某些情况下无需明确指定变量的类型&#xff0c;TypeScript编译器会自动为其推断出一个类型。这是TypeScript提供的一项强大功能&#xff0c;能够让代码既简洁又具有类型安全性。接下来&#xff0c;我们将详细探讨类型推论的使用场景、应用技巧&#…

在线商城系统有哪些必要做的功能

随着电商市场的不断扩大&#xff0c;单一的商户模式已不能满足消费者多样化的需求。多商户商城系统应运而生&#xff0c;为商家提供了一个共享资源、互利共赢的平台。那么&#xff0c;如何搭建一个稳定、高效的多商户商城系统呢&#xff1f; 一、明确需求与规划 在搭建之初&a…

2060:【例1.1】计算机输出

时间限制: 1000 ms 内存限制: 65536 KB 提交数:217106 通过数: 107259 【题目描述】 在屏幕上输出“Hello World!”。 【输入】 (无&#xff09; 【输出】 (无&#xff09; 【输入样例】 (无&#xff09; 【输出样例】 Hello World! #include<bits/stdc.h&g…

oracle临时表空间不释放

项目报错 nested exception is java.sql.SQLException: ORA-01652: unable to extend temp segment by 128 in tablespace TEMP 原因是临时表空间满了&#xff0c;临时表空间一直增长&#xff0c;未释放导致临时表空间使用率100%。 查询临时表空间使用率 --临时表空间利用率…

【位运算】【脑筋急转弯】2749. 得到整数零需要执行的最少操作数

作者推荐 视频算法专题 本文涉及知识点 2749. 得到整数零需要执行的最少操作数 给你两个整数&#xff1a;num1 和 num2 。 在一步操作中&#xff0c;你需要从范围 [0, 60] 中选出一个整数 i &#xff0c;并从 num1 减去 2i num2 。 请你计算&#xff0c;要想使 num1 等于 …