C#异步详解

异步编程是指在程序执行过程中,不需要等待某个操作完成,就可以继续执行后续的代码。比如我们开发了一个web页面中有一个上传文件功能,我们上传文件时使用异步操作,就不用等待文件的上传时间,可以先在网页上进行其他操作。但是如果我们的需求是等待上传文件完成之后才能进行下一步操作,比如我在boss上上传简历,然后根据附件简历生成在线简历,然后我在对在线简历进行优化,这时候就需要加一个await等待这个异步完成。

下面使用代码来举一个例子

创建一个 100000000个a 的超长字符串,然后把这个字符串写进d盘的文本里面

public static async Task Main(string[] args)
{
    string str = new string('a', 100000000);
    await File.WriteAllTextAsync("d:/1.txt", str);//加了await的异步写入
    File.WriteAllTextAsync("d:/2.txt", str);//异步写入
    File.WriteAllText("d:/3.txt", str);
}

打个断点 ,一步一步来执行

执行完第一行写入到d盘的1.txt时 ,d盘已经有了一个记事本,有很多的a,因为这句代码加了await,这里会等它执行完再到下一步。

 接着往下走,执行到最后一行代码时,虽然D盘也有2.txt了,但是由于我没有加await,此时并没有等第三句代码执行完。所以这个断点往下走时我们会发现并不会像上面一样等很久,因为异步方法会立刻返回到调用者,因此也叫(非阻塞方法)

可以看到记事本中有很多的a,但是很显然没有 100000000个,很显然是写到一半被我的断点停住了。

 

 把断点继续,此时最后两句代码一起在执行,分别往2.txt和3.txt写入。

在上面的方法中加入打印线程,看一下执行过程线程的变化

string str = new string('a', 100000000);

Console.WriteLine(Thread.CurrentThread.ManagedThreadId);

await File.WriteAllTextAsync("d:/1.txt", str);//加了await的异步写入
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);

File.WriteAllTextAsync("d:/2.txt", str);//异步写入
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);

File.WriteAllText("d:/3.txt", str);
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);

 打印结果显示,加了await的异步方法执行完后线程发生了变化 ,因为原有线程遇见await会被解放,用于执行异步任务的线程会在任务完成后返回到await处接替原有线程继续执行任务

再举一个例子,我们自己创建一个异步方法

public static  async Task MethodAsync()
{  
    await Task.Run(() =>
    {  
        for (int i = 0; i < 1000; i++)
        {  
            Console.WriteLine(" MethodAsync   "+i);  
        }  
            Console.WriteLine("异步线程=====>"+Thread.CurrentThread.ManagedThreadId);
    });  
}  

再创建一个普通方法

    public static void Method()
    {  
        for (int i = 0; i < 1000; i++)
        {  
            Console.WriteLine(" Method    " +i);  
        }  
            Console.WriteLine("普通方法线程=====>"+Thread.CurrentThread.ManagedThreadId);
    }  

在main方法中使用await调用异步方法

    public static async Task Main(string[] args)
    {
        Console.WriteLine("线程main =====>"+Thread.CurrentThread.ManagedThreadId);
        await MethodAsync();
        Console.WriteLine("线程main=====>"+Thread.CurrentThread.ManagedThreadId);
        Method();
        Console.WriteLine("线程main=====>"+Thread.CurrentThread.ManagedThreadId);
    }

 把方法停在普通方法前

控制台输出👇

 因为加了await,所以等待异步方法for循环完成,从控制台输出结果看出,main方法一开始的线程是1,在执行异步方法时线程是3,执行完异步方法后回到main方法,打印线程还是3,因此上面提到的

原有线程遇见await会被解放,用于执行异步任务的线程会在任务完成后返回到await处接替原有线程继续执行任务

这句话成立。

 那我们再试试不加await的

 还是一样停在刚刚的断点处,可是此时的两次主线程打印都是1,异步方法还没开始打印

 继续往下走,在控制台中发现,异步方法中新开了一个线程3,和普通方法交叉打印,最后打印主方法的线程也是原来的线程。

 

 

 

 说完await,我们再来看看async

async来修饰一个方法,表明这个方法是异步的,声明的方法的返回类型必须为:voidTaskTask<TResult>。方法内部必须含有await修饰的方法,如果方法内部没有await关键字修饰的表达式,哪怕函数被async修饰也只能算作同步方法,执行的时候也是同步执行的。

因此await和async是形影不离的,如下创建两个方法

    Task<string> ReadAsync()
    {
        return File.ReadAllTextAsync(@"D:\1.txt");
    }

    async Task<string> ReadAsync2()
    {
        return await File.ReadAllTextAsync(@"D:\1.txt");
    }

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JAVA_HOME变量的详细配置(图文)

用到Java项目的时候&#xff0c;有时候要用到Java_home&#xff0c;这个需要在系统配置中配置一下。如何操作呢&#xff1f;以下为详细的图文步骤。 1&#xff09;打开环境变量的窗口 2&#xff09;打开新建系统变量 3&#xff09;编辑JAVA_HOME 在变量名后输入JAVA_HOME,找到…

Ui自动化测试如何上传文件

前言 实施UI自动化测试的时候&#xff0c;经常会遇见上传文件的操作&#xff0c;那么对于上传文件你知道几种方法呢&#xff1f;今天我们就总结一下几种常用的上传文件的方法&#xff0c;并分析一下每个方法的优点和缺点以及哪种方法效率&#xff0c;稳定性更高 被测HTML代码…

centos直接部署express

centos直接部署express 以下是在CentOS上部署Express应用程序的一般步骤&#xff1a; 1.安装Node.js 在CentOS系统上安装Node.js。可以使用以下命令安装Node.js&#xff1a; sudo yum install nodejs2.安装npm 安装完Node.js后&#xff0c;还需要安装npm&#xff08;Node.…

Python爬虫被封ip解决方案

在使用 Python 程序进行网络爬虫开发时&#xff0c;可能因以下原因导致被封 IP 或封禁爬虫程序&#xff1a; 1、频繁访问网站 爬虫程序可能会在很短的时间内访问网站很多次&#xff0c;从而对目标网站造成较大的负担和压力&#xff0c;这种行为容易引起目标网站的注意并被封禁…

数据结构-队列

数据结构之队列 队列的概念顺序队列循环队列 顺序循环队列的ADT定义1、简单结构体定义2、初始化3、队列的清空4、计算队列的长度5、判断队列是否为空6、插入新的元素7、元素的删除8、遍历输出队列内的所有元素 链队列的ADT定义1、链队列简单结构体定义2、初始化链队列3、判断链…

神秘的临时对象

下面的程序输出什么&#xff1f;为什么&#xff1f; 程序意图&#xff1a; 在 Test() 中以 0 作为参数调用 Test(int i) 将成员变量 mi 的初始值设置为 0 运行结果&#xff1a; 成员变量 mi 的值为随机值 构造函数是一个特殊的函数 是否可以直接调用&#xff1f; 是否可以…

LVS+KeepAlived高可用负载均衡集群

LVSKeepAlived高可用负载均衡集群 1. 高可用群集的相关知识1.普通群集2.高可用群集(HA)3.Keepalived及其工作原理4.Keepalived体系主要模块及其作用5.健康检查方式&#xff08;学名&#xff1a;探针&#xff09; 二、脑裂的形成和解决1.产生脑裂的常见原因及解决方法2.脑裂预防…

谈找工作线上途径

谈找工作 目录概述需求&#xff1a; 设计思路实现思路分析1.51job2.拉勾网 猎聘网站智联招聘网站后记 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,make a better result,wait…

新能源汽车保养vr仿真教学软件为职业培训带来新的思路和方法

电动车电池更换VR虚拟体验是一种利用VR虚拟现实技术实现对电动车电池更换进行模拟仿真演示和实操训练的虚拟仿真实验教学课件&#xff0c;相比传统教学模式&#xff0c;有效提高学生的实践能力和技能水平。 通过VR技术模拟现场&#xff0c;使培训人员可以身临其境滴观摩操作过程…

在 PyTorch 中实现可解释的神经网络模型

动动发财的小手&#xff0c;点个赞吧&#xff01; 目的 深度学习系统缺乏可解释性对建立人类信任构成了重大挑战。这些模型的复杂性使人类几乎不可能理解其决策背后的根本原因。 ❝ 深度学习系统缺乏可解释性阻碍了人类的信任。 ❞ 为了解决这个问题&#xff0c;研究人员一直在…

c++Qt Creator调用 python 完整版 + 解决bug过程

文章目录 创建项目配置python环境导入Python库其他坑点Python.h 头文件报错ModuleNotFoundError: No module named encodings’ 完美解决找不到python文件 成功&#xff01; 文章首发于我的个人博客&#xff1a;欢迎大佬们来逛逛 创建项目 选择创建 qmake 项目&#xff1a; …

【C++】vector的模拟实现

目录 1.vector的结构2.构造函数2.1 无参构造2.2 以迭代器区间作为参数的构造函数2.3 构造n个value值 3.拷贝构造3.1 传统写法3.2 现代写法 4.赋值重载5.迭代器失效问题5.1 reserve和resize5.2 insert 5.3 erase4. 整体代码&#xff08;包含迭代器、析构函数等&#xff09; 1.ve…

springboot实验室管理系统-计算机毕设 附源码86757

springboot实验室管理系统 摘 要 验室管理系统是将实验室的分析仪器通过计算机网络连起来&#xff0c;采用科学的管理思想和先进的数据库技术&#xff0c;实现以实验室为核心的整体环境的全方位管理。它集用户管理&#xff0c;实验室信息管理&#xff0c;实验室预约管理&#x…

Java设计模式——策略模式

1. 策略模式简介 策略模式: 策略模式是一种行为型模式, 它将对象和行为分开, 将行为定义为一个行为接口和具体行为的实现 策略模式最大的特点是行为的变化, 行为之间可以相互替换 每个if判断都可以理解为一个策略. 本模式是的算法可独立于使用它的用户而变化 2. 模式结构 策略…

Flink 学习七 Flink 状态(flink state)

Flink 学习七 Flink 状态(flink state) 1.状态简介 流式计算逻辑中,比如sum,max; 需要记录和后面计算使用到一些历史的累计数据, 状态就是:用户在程序逻辑中用于记录信息的变量 在Flink 中 ,状态state 不仅仅是要记录状态;在程序运行中如果失败,是需要重新恢复,所以这个状态…

Java实训第七天——2023.6.13

文章目录 一、用Visual Studio Code写一个计算器二、同一个js被多个html引用三、js操作css四、DOM对象属性的操作案例五、js解析json 一、用Visual Studio Code写一个计算器 功能&#xff1a;实现简单的加减乘除 <!DOCTYPE html> <html lang"en"> <…

LeetCode 2481. 分割圆的最少切割次数

【LetMeFly】2481.分割圆的最少切割次数 力扣题目链接&#xff1a;https://leetcode.cn/problems/minimum-cuts-to-divide-a-circle/ 圆内一个 有效切割 &#xff0c;符合以下二者之一&#xff1a; 该切割是两个端点在圆上的线段&#xff0c;且该线段经过圆心。该切割是一端…

mapbox-gl 点位编辑功能

文章目录 前言方式一&#xff1a;借助 Marker添加自定义icon添加POI图层&#xff0c;绑定对应事件基于Marker交互创建自定义Marker编辑 / 创建POI 方式二&#xff1a;采用 mapbox-gl-draw 插件总结 前言 矢量在线编辑是gis常用的编辑功能&#xff0c;兴趣点&#xff08;POI&am…

kettle开发-Day38-超好用自定义数据处理组件

目录 前言&#xff1a; 一、半斤八两&#xff0c;都不太行 1、表输入&#xff0c;速度快&#xff0c;但不稳妥 2、稳的一批&#xff0c;但是慢的像蜗牛 二、各诉衷肠&#xff0c;合作共赢 1、表输入&#xff0c;高效数据插入 2、插入更新&#xff0c;一个都不能少 三、表输…

express的使用(四) nodejs转发表单到后台

原文链接 搬砖的林小白-express的使用(四) 个人博客地址&#xff0c;求关注&#xff0c;也希望大家在里面批评我的不足之处 看前提示 本篇所讲述的内容是node端转发前端发送过来的表单到第三方中&#xff0c;应用的场景有很多&#xff0c;如我们经常做的将文件存储到七牛云或…