C#学习系列相关之多线程(四)----async和await的用法
一、async、await用法的作用
async用法主要是用来作为修饰符将方法作为异步方法使用,await关键字只用作为在异步方法才能使用,也就是只有当方法有async修饰后,才能在方法中使用await,await后跟Task新的任务启动。(await和async是配对使用)
二、async、await用法实例
第一个关键点:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;namespace 线程test1005
{public delegate void test(string s1);class Program{static void Main(string[] args){test();for (int i = 0; i < 400; i++){Console.Write(0);}Console.Read();}public async static void test(){for (int i = 0; i < 300; i++){Console.Write(1);}await Task.Run(() =>{for (int i = 0; i < 300; i++){Console.Write(2);}});for (int i = 0; i < 300; i++){Console.Write(3);}}}
}
await的核心作用:如上述代码当中,我们在test函数中使用Task.Run开启新线程后,主线程和支线程交替执行,也就是输出结果为1,然后2和3交替输出,最后输出0,只是在函数内部开启支线程,并没有跳出函数。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;namespace 线程test1005
{public delegate void test(string s1);class Program{static void Main(string[] args){test();for (int i = 0; i < 1000; i++){Console.Write(0);}Console.WriteLine("0的支线程号为" + Thread.CurrentThread.ManagedThreadId);Console.Read();}public async static void test(){for (int i = 0; i < 300; i++){Console.Write(1);}Console.WriteLine("1的支线程号为" + Thread.CurrentThread.ManagedThreadId);Task.Run(() =>{for (int i = 0; i < 300; i++){Console.Write(2);}Console.WriteLine("2的支线程号为" + Thread.CurrentThread.ManagedThreadId);});for (int i = 0; i < 300; i++){Console.Write(3); }Console.WriteLine("3的支线程号为" + Thread.CurrentThread.ManagedThreadId);}}
}
运行结果为:

在添加await后,当输出2的时候,会跳出test函数,2和0交替输出,等待Task.run运行完,再继续执行函数后的内容,输出结果也就是1,2和0交替输出,最后再输出3,如果0的数量比较多,则0和3也会交替输出!
总结:test中的代码在await以前的代码都是在主函数的线程中输出,但是在await以后的代码会在Task.Run的线程中运行。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;namespace 线程test1005
{public delegate void test(string s1);class Program{static void Main(string[] args){test();for (int i = 0; i < 1000; i++){Console.Write(0);}Console.WriteLine("0的支线程号为" + Thread.CurrentThread.ManagedThreadId);Console.Read();}public async static void test(){for (int i = 0; i < 300; i++){Console.Write(1);}Console.WriteLine("1的支线程号为" + Thread.CurrentThread.ManagedThreadId);await Task.Run(() =>{for (int i = 0; i < 300; i++){Console.Write(2);}Console.WriteLine("2的支线程号为" + Thread.CurrentThread.ManagedThreadId);});for (int i = 0; i < 300; i++){Console.Write(3); }Console.WriteLine("3的支线程号为" + Thread.CurrentThread.ManagedThreadId);}}
}
运行结果如图:
提示:本人准备建立一个技术交流群,会将日常学习工作中遇到的问题和解决方案进行分享,同时也会将代码和学习资料上传进去,有什么不懂的问题可以咨询我!+v:SJS66-12
生活所迫打个广告,本人也代购莆田鞋,不是中间商,工厂直接取货,价格优惠质量保证,都是我自己前去挑选,可以视频选购验货!!希望大家支持!!!赚点生活费!!!+v:SJS66-12
第二个关键点:
await会返回一个结果,返回的结果类型是Task<resut>类型,当我们主函数需要该结果的result的时候,我们的代码会等待函数全部完成后才会继续执行。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;namespace 线程test1005
{public delegate void test(string s1);class Program{static void Main(string[] args){var tt=test();for (int i = 0; i < 1000; i++){Console.Write(0);}Console.WriteLine("0的支线程号为" + Thread.CurrentThread.ManagedThreadId);Console.WriteLine(tt.Result);for (int i = 0; i < 1000; i++){Console.Write(8);}Console.Read();}public async static Task<int> test(){for (int i = 0; i < 300; i++){Console.Write(1);}Console.WriteLine("1的支线程号为" + Thread.CurrentThread.ManagedThreadId);var result =await Task<int>.Run(() =>{for (int i = 0; i < 300; i++){Console.Write(2);}Console.WriteLine("2的支线程号为" + Thread.CurrentThread.ManagedThreadId);return 10;});for (int i = 0; i < 300; i++){Console.Write(3); }Console.WriteLine("3的支线程号为" + Thread.CurrentThread.ManagedThreadId);return result;}}
}
上述代码中当主函数中需要tt.result时,主函数代码会等待test函数运行完返回result结果后再继续执行后续代码。
运行结果为:

提示:async修饰的函数类型只有三种,void类型、Task和Task<T>!!!
Task.Run的单独返回类型为内部运行函数的返回值T,但await修饰后的返回值为Task<T>
参考文献:
C# async / await 用法_c# await_熊思宇的博客-CSDN博客
相关文章:
C#学习系列相关之多线程(四)----async和await的用法
一、async、await用法的作用 async用法主要是用来作为修饰符将方法作为异步方法使用,await关键字只用作为在异步方法才能使用,也就是只有当方法有async修饰后,才能在方法中使用await,await后跟Task新的任务启动。(awai…...
极智AI | 大模型优化之KV Cache
欢迎关注我的公众号 [极智视界],获取我的更多经验分享 大家好,我是极智视界,本文来介绍一下 大模型优化之KV Cache。 邀您加入我的知识星球「极智视界」,星球内有超多好玩的项目实战源码下载,链接:https://t.zsxq.com/0aiNxERDq 在大模型的优化中经常会听到的一个技术叫…...
Android 使用 registerForActivityResult() 打开系统相册或相机获取图像
一、简介 当使用了 AndroidX 后,发现 startActivityForResult() 标记为过时了,而是推荐我们使用 registerForActivityResult() 函数。 registerForActivityResult() 函数是 Android 中用于启动 Activity 结果回调的新方式。这个函数的目的是简化在 Act…...
如何制作网页 ico
1. 制作 icon 可以通过 https://www.iconfont.cn/collections/detail?spma313x.7781069.1998910419.de12df413&cid13720 或者自己在 PPT 制作,然后截图导出png 文件。 2. 转换为 ico 文件 使用:https://www.bitbug.net/ 上传并且转换成自己要的…...
golang gorm 增删改查以及使用原生SQL(以操作mysql为例)
gorm mysql增删改查 model定义 package _caseimport "gorm.io/gorm"func init() {DB.Migrator().AutoMigrate(Teacher{}, Course{}) } type Roles []stringtype Teacher struct {gorm.ModelName string gorm:"size:256"Email string gorm:&q…...
代码随想录 单调栈part2
503. 下一个更大元素 II 给定一个循环数组 nums ( nums[nums.length - 1] 的下一个元素是 nums[0] ),返回 nums 中每个元素的 下一个更大元素 。 数字 x 的 下一个更大的元素 是按数组遍历顺序,这个数字之后的第一个比它更大的数…...
详解利用高斯混合模型拆解多模态分布 + 精美可视化
文章目录 一、前言二、主要内容三、总结🍉 CSDN 叶庭云:https://yetingyun.blog.csdn.net/ 一、前言 本文旨在介绍如何利用高斯混合模型(Gaussian Mixture Models,简称 GMMs)将一维多模态分布拆分为多个分布。作为统计 / / /机器学习领域常用的概率模型...
排序算法之【归并排序】
📙作者简介: 清水加冰,目前大二在读,正在学习C/C、Python、操作系统、数据库等。 📘相关专栏:C语言初阶、C语言进阶、C语言刷题训练营、数据结构刷题训练营、有感兴趣的可以看一看。 欢迎点赞 👍…...
Qt中QTimer定时器的用法
Qt中提供了两种定时器的方式一种是使用Qt中的事件处理函数,另一种就是Qt中的定时器类QTimer。 使用QTimer类,需要创建一个QTimer类对象,然后调用其start()方法开启定时器,此后QTimer对象就会周期性的发出timeout()信号。 1.QTimer…...
vue-组件定义注册使用
vue组件使用的步骤 定义组件注册组件使用组件 定义组件 Vue.extend(options) 其中options和new Vue(options)出入的options对象几乎一样,但是也有不同。 创建 el不用写—最终所有组件需要经过一个vm的管理,由vm的el决定服务哪个容器。 data必须写成函…...
斑馬打印機打印中文
创建项目 首先說一下,本文章是借鉴了其他大佬的文章,然后我记录一下的文章。 首先创建好一个.net framework的winform项目。 这里面主要用到两个库文件: Fnthex32.dll、LabelPrint.dll。 Fnthex32这个有8位参数和9位参数的,我这…...
(一)Apache log4net™ 手册 - 介绍
0、相关概念 Log4j 几乎每个大型应用程序都包含自己的日志记录或跟踪 API。根据这一规则,E.U. SEMPER 🌹项目决定编写自己的跟踪 API。那是在 1996 年初。经过无数次的增强、几个化身和大量的工作,API 已经发展成为 log4j —— 一个流行的 Ja…...
基于Java的民宿管理系统设计与实现(源码+lw+部署文档+讲解等)(民宿预约、民宿预订、民宿管理、酒店预约通用)
文章目录 前言具体实现截图论文参考详细视频演示代码参考源码获取 前言 💗博主介绍:✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技…...
039:mapboxGL更换地图上的鼠标样式
第039个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+mapbox中更换地图上的鼠标的样式。 直接复制下面的 vue+mapbox源代码,操作2分钟即可运行实现效果 文章目录 示例效果配置方式示例源代码(共74行)相关API参考:专栏目标示例效果 配置方式 1)查看基础设置:htt…...
【云原生】K8S对外服务之Ingress
目录 一、Ingress 简介1.1Ingress 组成1.3Ingress-Nginx 工作原理 二、部署 nginx-ingress-controller2.1部署ingress-controller Pod及相关资源2.2ingress 暴露服务的方式2.3 采用方式二:DaemonSetHostNetworknodeSelector 三、采用方式二:DeploymentNo…...
分布式锁如何实现
分布式是现在的比较主流的技术,常常和微服务一起出现。那么对于多个实例之间,如何证分布式系统中多个进程或线程同步访问共享资源呢?我们其实一想到的就是锁,我们在java里边有 synchronized, 在python里有lock,但是这个…...
Mysql存储-EAV模式
Mysql存储-EAV模式 最近又又又搞一点新东西,要整合不同业务进行存储和查询,一波学习过后总结了一下可扩展性MAX的eav模式存储。 在eav这里的数据结构设计尤为关键,需要充分考虑你需要使用的字段、使用场景,当数据结构设计完成后便…...
全局变量报错:\Output\STM32.axf: Error: L6218E: Undefined symbol
全局变量报错: .\Output\STM32.axf: Error: L6218E: Undefined symbol key_num (referred from main.o). 这里只说全局变量哦,这是因为你在调用的.c文件里 把定义写在了函数里面,写函数外面就没事了 改为: .h的声明文件根本不用写…...
算法错题簿(持续更新)
自用算法错题簿,按算法与数据结构分类 python1、二维矩阵:记忆化搜索dp2、图论:DFS3、回溯:129612964、二叉树:贪心算法5、字符串:记忆化搜索6、01字符串反转:结论题7、二进制数:逆向…...
基于Springboot实现疫情网课管理系统项目【项目源码+论文说明】
基于Springboot实现疫情网课管理系统演示 摘要 随着科学技术的飞速发展,各行各业都在努力与现代先进技术接轨,通过科技手段提高自身的优势;对于疫情网课管理系统当然也不能排除在外,随着网络技术的不断成熟,带动了疫情…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...
【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案
目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后,迭代器会失效,因为顺序迭代器在内存中是连续存储的,元素删除后,后续元素会前移。 但一些场景中,我们又需要在执行删除操作…...
elementUI点击浏览table所选行数据查看文档
项目场景: table按照要求特定的数据变成按钮可以点击 解决方案: <el-table-columnprop"mlname"label"名称"align"center"width"180"><template slot-scope"scope"><el-buttonv-if&qu…...
拟合问题处理
在机器学习中,核心任务通常围绕模型训练和性能提升展开,但你提到的 “优化训练数据解决过拟合” 和 “提升泛化性能解决欠拟合” 需要结合更准确的概念进行梳理。以下是对机器学习核心任务的系统复习和修正: 一、机器学习的核心任务框架 机…...
【技巧】dify前端源代码修改第一弹-增加tab页
回到目录 【技巧】dify前端源代码修改第一弹-增加tab页 尝试修改dify的前端源代码,在知识库增加一个tab页"HELLO WORLD",完成后的效果如下 [gif01] 1. 前端代码进入调试模式 参考 【部署】win10的wsl环境下启动dify的web前端服务 启动调试…...
Cursor AI 账号纯净度维护与高效注册指南
Cursor AI 账号纯净度维护与高效注册指南:解决限制问题的实战方案 风车无限免费邮箱系统网页端使用说明|快速获取邮箱|cursor|windsurf|augment 问题背景 在成功解决 Cursor 环境配置问题后,许多开发者仍面临账号纯净度不足导致的限制问题。无论使用 16…...
从0开始一篇文章学习Nginx
Nginx服务 HTTP介绍 ## HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。 ## HTTP工作在 TCP/IP协议体系中的TCP协议上&#…...
