C# 细说async/await的用法

news2024/11/24 8:28:55

目录

一,引言

二,实例演示

2.1 多线程同步执行下载任务,任务完成后通知

2.2 异步执行下载任务,任务完成后通知

三,async/await的用法

3.1 跨线程修改UI控件

3.2 异步获取数据


一,引言

首先先来区分一下,同步方法,异步方法和多线程:

  • 同步方法:调用时需要等待返回结果(相当于阻塞了该线程),才可以继续往下执行业务
  • 异步方法:调用时无须等待返回结果(等待时释放线程),可以继续往下执行业务
  • 多线程:在主线程之外开启一个新的线程去(增加线程,同步执行)执行业务

 关于async/await:

  1.  async和await关键字是C# 5.0时代引入的,它是一种异步编程模型
  2. 它们本身并不创建新线程,但可以在自行封装的async中利用Task.Run开启新线程
  3. 方法体中使用await,方法也必须声明为async(成对出现),如果没有await,async关键字也没有意义。

async/await的理解:

个人理解:await可以看着是代码执行的分裂点,当程序执行到await后面的语句时,首先系统会将当前的线程释放(回归线程池,其他程序可调用),并捕获当前上下文(打上标记),进入等待(注意:期间没有线程阻塞)。当await后语句执行完毕,根据标记点调用线程(从线程池随机捕获线程,有概率是原来的线程)执行下面的语句。

二,实例演示

2.1 多线程同步执行下载任务,任务完成后通知

static void Main(string[] args)
        {
            DownloadHandle();
            Console.ReadLine();
        }
        public static  void DownloadHandle()
        {
            Console.WriteLine("下载开始!->主线程ID:" + Thread.CurrentThread.ManagedThreadId);
            var t= Download();
            Task.WaitAll(t);
            Console.WriteLine("下载完成!->主线程ID:" + Thread.CurrentThread.ManagedThreadId);
        }
        public static Task Download()
        {
            return Task.Run(() =>
            {
                Console.WriteLine("下载线程ID:->" + Thread.CurrentThread.ManagedThreadId);
                Console.WriteLine("10%");
                Console.WriteLine("30%");
                Console.WriteLine("50%");
                Console.WriteLine("60%");
                Console.WriteLine("80%");
                Console.WriteLine("99%");
                Console.WriteLine("100%");
            });
        }

结果输出:

可以看的,在多线程下载任务时,通过Task.WaitAll(t) 等待线程执行完毕后,主线程一直处于阻塞状态。

2.2 异步执行下载任务,任务完成后通知

        static void Main(string[] args)
        {
            DownloadHandle();
            Console.ReadLine();
        }
        public static async void DownloadHandle()
        {
            Console.WriteLine("下载开始!->主线程ID:" + Thread.CurrentThread.ManagedThreadId);
            await Download();
            Console.WriteLine("下载完成!->主线程ID:" + Thread.CurrentThread.ManagedThreadId);
        }
        public static Task Download()
        {
            return Task.Run(() =>
            {
                Console.WriteLine("下载线程ID:->" + Thread.CurrentThread.ManagedThreadId);
                Console.WriteLine("10%");
                Console.WriteLine("30%");
                Console.WriteLine("50%");
                Console.WriteLine("60%");
                Console.WriteLine("80%");
                Console.WriteLine("99%");
                Console.WriteLine("100%");
            });
        }

可以看的,在异步下载任务时,主线程未被阻塞。

异步方法async/await的返回值类型一般都是Task或者Task<T>类型的,当返回值为Task时(即方法的返回值类型为void),我们可以直接return Task.Run(()=>{}),而不必await Task.Run(()=>{}),这样也可从一定程度上提高代码执行效率。另外,不推荐使用async 修饰void返回值,会有异常处理方面的问题。

三,async/await的用法

async/await并不能提升代码的执行速度,但可以提高响应能力(吞吐量),即使用异步方式在同一时间可以处理更多的请求。

  • 使用同步方式,线程会被耗时操作一直占用,直到耗时操作结束;
  • 使用异步方式,程序走到await关键字会立即return,释放线程,剩下的代码将放到一个回调,耗时操作完成时才会回调执行。

因此:

  • 对于计算密集型工作,使用多线程
  • 对于IO密集型工作,采用异步机制

从代码整体的架构设计来说,由于async/await语法容易使得程序被await传染,因此不要从最里面的方法启动线程,而是把启动线程的代码放到最外面,这样一来绝大部分方法就都不再需要用async修饰了,方法就都可以用正常的方式开发了。

3.1 跨线程修改UI控件

通过async/await的机制,可以非常简洁轻松的实现跨线程修改UI控件的问题,也不用使用Invoke。(因为本质上还是在原来的线程上修改的,还没有阻塞UI界面)

private async void button1_Click(object sender, EventArgs e)
        {
            var t = Task.Run(() => {
                Thread.Sleep(5000);
                return "Hello I am TimeConsumingMethod";
            });
            textBox1.Text = await t;
        }

3.2 异步获取数据

在写后端的数据异步处理时,通过async/await语法也可轻易实现,为了防止async/await语法传染,将启动线程的代码放在了最外层,这样在Click事件中就可以正常调用了,不用在增加async关键字了。

 private void button2_Click(object sender, EventArgs e)
        {
            AsyncFunc();
        }
        private async Task AsyncFunc()
        {
            DataTable dt = await FecthData();
            this.dataGridView1.DataSource = dt;
        }
        private async Task<DataTable> FecthData()
        {
            DataTable dt = null;
            await Task.Run(() =>
            {
                dt = new DataTable();
                dt.Columns.Add("id", typeof(int));
                dt.Columns.Add("name");
                for (int i = 0; i < 10000; i++)
                {
                    dt.Rows.Add(new object[] { i, "name" + i.ToString() });
                }
                Thread.Sleep(1000);
            });
            return dt;
        }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/766975.html

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

相关文章

【Go】实现一个代理Kerberos环境部分组件控制台的Web服务

实现一个代理Kerberos环境部分组件控制台的Web服务 背景安全措施引入的问题SSO单点登录 过程整体设计路由反向代理登录会话组件代理YarnHbase 结果 背景 首先要说明下我们目前有部分集群的环境使用的是HDP-3.1.5.0的大数据集群&#xff0c;除了集成了一些自定义的服务以外&…

python opencv 级联Haar多目标检测

一、基于OpenCV的haar分类器实现笑脸检测 1、Haar分类器介绍 &#x1f680;Haar分类器是一种基于机器学习的目标检测算法&#xff0c;它使用Haar特征描述图像中的目标。Haar特征是基于图像亮度的局部差异计算得出的&#xff0c;可以用来描述目标的边缘、角落和线条等特征。 使用…

Jenkins (一)

Jenkins (一) Docker Jenkins 部署 一. 安装 jenkins $ mkdir -p /home/tester/data/docker/jenkins $ vim jenkins:lts-jdk11.sh./jenkins:lts-jdk11.sh 内容 #! /bin/bash mkdir -p /home/tester/data/docker/jenkins/jenkins_homesudo chown -R 1000:1000 /home/tester/da…

利用LightHouse进行合理的页面性能优化,看这一篇就够了!

利用LightHouse进行合理的页面性能优化&#xff0c;看这一篇就够了&#xff01; 前言一. Lighthouse下载1.1 相关指标概念1.2 Lighthouse 优化建议 二. 跟着 Lighthouse 进行性能优化2.1 Enable text compression 开启文本压缩2.2 Resize images 重新设定合适大小的图片2.3 Eli…

Java阶段五Day08

Java阶段五Day08 文章目录 Java阶段五Day08内容回顾学习内容目的自动配置原理SPI-API:一对类似的概念 自定义Starter属性配置问题 网关组件SpringCloud Gateway网关架构微服务网关介绍Spring Cloud Gateway&#xff08;技术选型&#xff09;网关转发入门案例明确案例需求实现案…

学习系统编程No.31【多线程互斥与同步】

引言&#xff1a; 北京时间&#xff1a;2023/7/16/14:32&#xff0c;摆烂至今&#xff0c;在耍这方面&#xff0c;谁能比我行&#xff0c;哈哈哈&#xff0c;乐观&#xff01;欠了一堆课要补&#xff0c;等我们把线程相关知识学完&#xff0c;对于系统编程方面我们搞定的就差不…

二分类结局变量Logistic回归临床模型预测——分训练集和测试集(完结)

1. 介绍 2. 基线特征 3. 单因素多因素logistic回归分析及三线表 4. 构建临床列线图模型 5. 模型评价 6. 外部数据集验证 7. 另一种发文章的办法,分训练集和测试集,分析上述3-6节的内容 这里就讲一下如何分训练集和测试集,其余的步骤和之前是一样的,分训练集和测试集用…

Fiddler网络调试器,抓包工具供大家学习研究参考

Fiddler 是一个 http 协议调试代{过}{滤}理工具&#xff0c;它能够记录并检查所有你的电脑和互联网之间的 http 通讯&#xff0c;设置断 点&#xff0c;查看所有的“进出”Fiddler 的数据(指 cookiehtmljscss等文件)。 Fiddler 要比其他的网络调试器要更加简单&#xff0c;因为…

从Vue2到Vue3【零】——Vue3简介

系列文章目录 内容链接从Vue2到Vue3【零】Vue3简介及创建 文章目录 系列文章目录前言一、Vue3的发布带来了什么1.1 性能提升1.2 源码升级1.3 支持TypeScript1.4 新特性1.5 支持 vue3 的UI组件库 二、创建Vue3.0工程2.1 什么是Vite2.2 利用Vite创建Vue3.0工程2.3 利用vue-cli脚…

下载最新版 VC_redist.x86.exe / VC_redist.x64.exe for Visual Studio 2015, 2017, 2019, and 2022

目录 1、如何处理程序需要的C/C运行时库&#xff1f; 2、VC_redist.x64.exe的主界面以及支持的命令行参数 3、到微软官网上下载最新版本的VC_redist.x86.exe / VC_redist.x64.exe VC常用功能开发汇总&#xff08;专栏文章列表&#xff0c;欢迎订阅&#xff0c;持续更新...&a…

总结几个GPT的超实用之处【附带Python案例】

GPT&#xff08;Generative Pre-trained Transformer&#xff09;是人工智能领域中最受欢迎的预训练语言模型之一&#xff0c;由OpenAI开发。该模型使用深度学习技术&#xff0c;可以自动生成各种文本&#xff0c;如文章、日记、小说等。GPT的超实用之处有很多&#xff0c;下面…

【Ubuntu 20.04LTS系统】安装CUDA11.8、cuDNN,可进行CUDA版本切换

Ubuntu 20.04LTS系统安装CUDA11.8、cuDNN&#xff0c;可进行CUDA版本切换 1. 更改为清华源并更新软件列表和依赖项2. 安装CUDA3. 安装cuDNN4. CUDA版本切换 1. 更改为清华源并更新软件列表和依赖项 https://mirrors.tuna.tsinghua.edu.cn/help/ubuntu/ # 默认注释了源码镜像以提…

java项目之毕业生就业信息管理系统(ssm+mysql+jsp)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于ssm的毕业生就业信息管理系统。技术交流和部署相关看文章末尾&#xff01; 开发环境&#xff1a; 后端&#xff1a; 开发语言&#xff1a;Java …

哇~真的是你呀!今天是LINUX中的SSH服务。

目录 前言 一、概述 二、身份验证机制及验证过程 三、加密机制 四、基本参数 五、基本操作 六、操作 前言 SSH&#xff08;Secure Shell&#xff09;是一种加密网络协议&#xff0c;用于远程登录和安全传输数据。在Linux系统中&#xff0c;SSH服务是一种常见的远程管理工具&am…

python copy.copy与copy.deepcopy 区别

结论 b a.copy(): 浅拷贝, a 和 b 是一个独立的对象&#xff0c;但他们的子对象还是指向统一对象&#xff08;是引用&#xff09;。 b copy.deepcopy(a): 深拷贝, a 和 b 完全拷贝了父对象及其子对象&#xff0c;两者是完全独立的。 import copy origin [1, 2, [3, 4]]…

CS拒绝连接,Cobalt Strike连接失败,Cobalt Strike使用方法(二)

本文主要介绍Cobalt Strike的界面及使用方法。 界面 菜单介绍 Cobalt Strike New Connection // 新建连接&#xff0c;可连接多个服务器端 Preferences // 设置Cobal Strike界面、控制台、以及输出报告样式、TeamServer连接记录 Visualization // 主要展…

精益生产有哪些管理工具?

精益生产有哪些管理工具&#xff1f; 一、什么是精益生产 智能制造是落实我国制造强国战略的重要举措&#xff0c;加快推进智能制造&#xff0c;是加速我国工业化和信息化深度融合、推动制造业供给侧结构性改革的重要着力点&#xff0c;对重塑我国制造业竞争新优势具有重要意义…

java项目---2048

目录 游戏介绍 游戏玩法 全代码 &#xff08;1&#xff09;Main类&#xff1a; &#xff08;2&#xff09;GamePanel类 &#xff08;3&#xff09;Card类 &#xff08;4&#xff09;GameFrame类 项目设计思路 1.绘制一个窗口 2.创建菜单 3.创建所有空白卡片 &…

项目经理在日常管理工作中需要注意什么?

项目管理的核心在于以项目经理为主导的团队协作&#xff0c;项目经理需要管理团队成员&#xff0c;保障团队的产出和效能。因此&#xff0c;项目经理需要具备多种能力&#xff0c;如沟通能力、管理能力、洞察人心的能力等&#xff0c;才能有效推动项目进展。 1、制定计划是项…

如何更改idea的背景,以及显示某些属性

idea项目无法正常显示的问题 在idea中右侧的属性都不存在的解决方法,或左边的不显示,我浏览了很多的文章才找到的解决办法,在这里分享给大家 就可以显示出来了,因为我原来已经显示了,当我取消后就看不到了 修改背景 1.先进入到设置的页面 选择完成后点击ok把设置关了就设置成功…