C# 异步调用aysnc await

一、基本概念

在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.mzph.cn/news/740795.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ubuntu20.04 创建ros环境、创建rospackage

roswiki教程&#xff1a;https://wiki.ros.org/cn/ROS/Tutorials 环境准备 安装ros环境 这里选择noetic版本的ros&#xff0c;安装步骤参考&#xff1a;https://zhuanlan.zhihu.com/p/662284005 创建工作空间 这里我在用户目录下创建catkin的工作目录catkin_ws &#xff0…

Linux 多线程开发

第三章 Linux 多线程开发 3.1 线程3.1.2 线程操作3.1.2 线程属性 3.2 线程同步3.2.1 互斥量/锁3.2.2 死锁3.2.3 读写锁 3.3 生产者消费者模型3.3.1 条件变量3.3.2 信号量/灯 网络编程系列文章&#xff1a; 第1章 Linux系统编程入门&#xff08;上&#xff09; 第1章 Linux系统…

TSINGSEE青犀煤矿矿井视频监控与汇聚融合管理视频监管平台建设方案

一、背景需求 随着我国经济的飞速发展&#xff0c;煤炭作为我国的主要能源之一&#xff0c;其开采和利用的重要性不言而喻。然而&#xff0c;煤矿事故频发&#xff0c;不仅造成了巨大的人员伤亡和财产损失&#xff0c;也对社会产生了深远的负面影响。视频监控系统作为实现煤矿智…

【Rockchip android7.1 平台rtl8821cs wifi移植调试】

Rockchip 平台rtl8821cs wifi移植调试 问题描述解决方法 郑重声明:本人原创博文&#xff0c;都是实战&#xff0c;均经过实际项目验证出货的 转载请标明出处:攻城狮2015 Platform: Rockchip rk3128 OS:Android 7.1.2 Kernel: 3.10 问题描述 客户需要在现在的板子上调一款RTL882…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的商品识别系统(深度学习+UI界面+训练数据集+Python代码)

摘要&#xff1a;在零售行业的技术进步中&#xff0c;开发商品识别系统扮演着关键角色。本博文详细阐述了如何利用深度学习技术搭建一个高效的商品识别系统&#xff0c;并分享了一套完整的代码实现。系统采用了性能强劲的YOLOv8算法&#xff0c;同时对YOLOv7、YOLOv6、YOLOv5等…

华为OD机试 - 字符串化繁为简(Java 2024 C卷 200分)

目录 专栏导读一、题目描述示例&#xff1a; 二、输入描述三、输出描述1、输入2、输出3、说明 四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2024C卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&…

2024蓝桥杯每日一题(区间合并)

一、第一题&#xff1a;挤牛奶 解题思路&#xff1a;区间合并 区间合并模板题 【Python程序代码】 n int(input()) a [] for i in range(n):l,r map(int,input().split())a.append([l,r]) def cmp(x):return x[0],x[1] a.sort(keycmp) res1,res20,0 st,ed a[0][0…

windows、Linux下操作命令

1、Regedit 查看策略表 2、Msconfig 查看系统配置 3、Taskmgr 启动任务管理器 4、Eventvwr,msc 打开日志的命令5、Gpedit.msc 打开本地组策略6、Compmgmt.msc 计算机管理 7、Lusrmgr.msc 打开用户与组 8、Taskschd 打开计划任务 9、Net user xxx /add 添加用户 10、Net …

CSS浮动引起的问题和解决方案

问题&#xff1a; 高度塌陷&#xff1a;当所有的子元素浮动的时候&#xff0c;且父元素没有设置高度&#xff0c;这时候父元素就会产生高度塌陷。 解决方案&#xff1a; 1&#xff1a;给父元素单独定义高度 缺点&#xff1a;子元素高超过父级时&#xff0c;会出现溢出 …

如何系统的学习Python——装饰器

装饰器是 Python 中强大而灵活的功能&#xff0c;用于在不修改函数代码的情况下&#xff0c;增强或修改函数的行为。装饰器通常用于在函数执行前或执行后添加一些额外的功能。 下面是装饰器的基本概念和使用方法&#xff1a; 1. 函数的基本结构&#xff1a; 在理解装饰器之前…

visualization_msgs::Marker 的pose设置,map坐标系的3d box显示问题

3D框显示 3D框显示可以使用visualization_msgs::Marker::LINE_LIST或者LINE_STRIP&#xff0c;前者使用方法需要指明线的两个端点&#xff0c;后者自动连接相邻两个点。 姿态问题 网上看了一些&#xff0c;没有涉及到朝向设置&#xff0c;Pose.orientation默认构造为4个0 至…

Python环境下一维时间序列的小波尺度谱和时间平均小波谱(基于Morlet小波)

小波分析是较好的非平稳信号分析方法之一&#xff0c;它通过伸缩和平移运算对信号进行多尺度细化分析&#xff0c;能够在不同的尺度上描述信号的局部特征&#xff0c;为微弱故障特征信号的检测提供了有效的工具。小波尺度谱可看作一个有恒定相对带宽的谱图&#xff0c;能够反映…

模拟电子技术实验(一)

单选题 1.本实验实际操作步骤都有哪些&#xff1f; A. 实验箱上的电压测量、实验箱上的电位器测量、5K、1 0V方波信号测 量。 B. 实验箱上的电压测量、实验箱上的电位器测量、5K、1 0V正弦波信号测 量。 C. 实验箱上的电压测量、实验箱上的数码管测量、5K、1 0V方波信号测 量…

Java剖析 : HashMap底层存储数据的结构 | HashSet添加不重复元素底层原理

HashSet底层剖析 前言&#xff1a; 我们知道Set中所存储的元素是不重复的&#xff0c;那么Set接口的实现类HashSet在添加元素时是怎么避免重复的呢&#xff1f; ★ HashSet在添加元素时&#xff0c;是如何判断元素重复的? ● 在底层会先调用hashCode()&#xff0c…

LeetCode题练习与总结:搜索旋转排序数组

一、题目 整数数组 nums 按升序排列&#xff0c;数组中的值 互不相同 。 在传递给函数之前&#xff0c;nums 在预先未知的某个下标 k&#xff08;0 < k < nums.length&#xff09;上进行了 旋转&#xff0c;使数组变为 [nums[k], nums[k1], ..., nums[n-1], nums[0], n…

OpenAI:ChatGPT API 文档之 Embedding

在自然语言处理和机器学习领域&#xff0c;"embeddings" 是指将单词、短语或文本转换成连续向量空间的过程。这个向量空间通常被称为嵌入空间&#xff08;embedding space&#xff09;&#xff0c;而生成的向量则称为嵌入向量&#xff08;embedding vector&#xff0…

14---DVI电路设计

视频链接 DVI硬件电路设计01_哔哩哔哩_bilibili DVI电路设计 1、DVI的简介 DVI(Digital Visual Interface)&#xff0c;即数字视频接口。它是1998年9月&#xff0c;在Intel开发者论坛上成立的&#xff0c;由Silicon Image、Intel(英特尔)、Compaq(康柏)、IBM(国际商业机器公…

时序数据库:TDengine整体架构

文章目录 [toc]一、集群与基本逻辑单元1.主要逻辑单元2.节点之间的通讯3.一个典型的消息流程 二、存储模型与数据分区、分片1.存储模型2.数据分片3.数据分区4.负载均衡 三、数据写入与复制流程1.Master Vnode 写入流程2.Slave Vnode 写入流程3.主从选择4.同步复制 四、缓存与持…

关于SpringSecurity出现Failed to evaluate expression ‘ps.hasAuthority(‘role‘)‘

1. 问题描述 在使用SpringSecurity对接口进行权限校验时&#xff0c;报错java.lang.IllegalArgumentException: Failed to evaluate expression ps.hasAuthority(role)。 2. 解决方案 2.1 查看是否添加注解 对于SpringSecurity对配置类&#xff0c;我们需要添加注解EnableGlo…

五 超级数据查看器 讲解稿 列表功能2

五 超级数据查看器 讲解稿 列表功能2 点击此处 以新页面 打开B站 播放教学视频 点此下载 百度手机助手 下载地址4 讲解稿全文&#xff1a; 大家好&#xff0c;今天我们讲解一下&#xff0c;超级数据查看器列表界面&#xff0c;分为1-2两集。这是第二集 继续讲解弹出式菜单…