(十)异步-什么是异步(1)

news/2024/4/15 13:48:45

一、什么是异步

启动程序时,系统会在内存中创建一个新的进程。

进程: 构成运行程序的资源的集合。这些资源包括虚地址空间、文件句柄和程序运行所需的其他许多东西。

在进程内部,系统创建了一个称为线程的内核对象,它代表了真正执行的程序。(线程是“执行线程”的简称。)一旦进程建立,系统会在 Main 方法的第一行语句处开始线程的执行。

关于线程:

  • 默认情况下,一个进程只包含一个线程(主线程),从程序的开始一直执行到结束。
  • 线程可以派生其他线程(子线程),因此在任意时刻,一个进程都可能包含不同状态的多个线程,它们执行程序的不同部分。
  • 如果一个进程拥有多个线程,它们将共享进程的资源。
  • 系统为处理器执行所调度的单元是线程,不是进程。

不使用异步的示例:
在我的电脑上,书上的示例中 CountCharacters(1, “htttp://microsoft.com” ); 里调用 DownloadString 方法会卡很久,可能传入的这个微软官方网的服务器有问题。(经我经验所知,微软官方网在某些时候就调用加载这一步时常会变得很慢,尤其登录微软账号的时候,显得更明显)于是我就直接换了个百度首页的地址来测试。

 class MyDownloadString{Stopwatch sw = new Stopwatch();const int LargeNumber = 6000000;public void DoRun(){sw.Start();int t1 = CountCharacters(1, "https://www.baidu.com/");int t2 = CountCharacters(2, "http://www.illustratedcsharp.com");CountToALargeNumber(1);CountToALargeNumber(2);CountToALargeNumber(3);CountToALargeNumber(4);Console.WriteLine($"Chars in https://www.baidu.com/   :{t1}");Console.WriteLine($"Chars in http://www.illustractedcsharp.com   :{t2}");}//获取网页源代码内容的长度private int CountCharacters(int id,string uriString){WebClient wc1 = new WebClient();//执行此处记录下时间值Console.WriteLine("Starting call {0}   :  {1, 4:N0} ms",id, sw.Elapsed.TotalMilliseconds);//需要时间下载并获取网页源代码string result = wc1.DownloadString(new Uri(uriString));Console.WriteLine("  Call {0} completed:    {1, 4:N0}ms",id, sw.Elapsed.TotalMilliseconds);return result.Length;}//每间隔一次时间,打印结果。//该方法在书上是有两个形参的,//但是我觉得有些多余(可能作者为了使代码规范化吧)//我为了简便就只使用一个形参private void CountToALargeNumber(int id){//循环作用:为了让程序执行一段时间,才打印一次结果,以方便查看计数值//如果不执行循环,以下打印结果很可能都是相同值。for (long i = 0; i < LargeNumber; i++);Console.WriteLine("  End counting {0}  :   {1,  4:N0}ms",id, sw.Elapsed.TotalMilliseconds);}}class Program{static void Main(string[] args){MyDownloadString ds = new MyDownloadString();ds.DoRun();Console.ReadKey();}}

输出结果:

Starting call 1 : 1 ms
Call 1 completed: 694ms
Starting call 2 : 694 ms
Call 2 completed: 3,147ms
End counting 1 : 3,188ms
End counting 2 : 3,235ms
End counting 3 : 3,280ms
End counting 4 : 3,323ms
Chars in https://www.baidu.com/ :9269
Chars in http://www.illustractedcsharp.com :5164

由输出结果可知,执行 DoRun 方法时,该方法里的代码都是按照顺序来执行的。也就是说,每调用一行代码之前,都得要等待上一行代码执行完毕之后才能执行。这里的示例中,由于 调用 DownloadString 方法是需要请求网络时间的, 所以需要等待 DownloadString 方法执行完毕之后,才能执行下一行代码。

请添加图片描述

使用异步的示例

根据上面的示例,把CountCharacters 方法重写为异步调用的方法:
把 DownloadString 改为 DownloadStringTaskAsync,即改为异步调用方法。

      class MyDownloadString{Stopwatch sw = new Stopwatch();const int LargeNumber = 6000000;public void DoRun(){sw.Start();//此处代码修改Task<int> t1 =  CountCharacters(1, "https://www.baidu.com/");Task<int> t2 = CountCharacters(2, "http://www.illustratedcsharp.com");CountToALargeNumber(1);CountToALargeNumber(2);CountToALargeNumber(3);CountToALargeNumber(4);Console.WriteLine($"Chars in https://www.baidu.com/   :{t1.Result}");//此处代码修改Console.WriteLine($"Chars in http://www.illustractedcsharp.com   :{t2.Result}");//此处代码修改}//获取网页源代码内容的长度,此处代码修改private async Task<int> CountCharacters(int id, string uriString){WebClient wc1 = new WebClient();//执行此处记录下时间值Console.WriteLine("Starting call {0}   :  {1, 4:N0} ms",id, sw.Elapsed.TotalMilliseconds);//需要时间下载并获取网页源代码var result = await wc1.DownloadStringTaskAsync(new Uri(uriString));//此处代码修改wc1.DownloadString(new Uri(uriString));Console.WriteLine("  Call {0} completed:    {1, 4:N0}ms",id, sw.Elapsed.TotalMilliseconds);return result.Length;}//每间隔一次时间,打印结果private void CountToALargeNumber(int id){//循环作用:为了让程序执行一段四件,才打印一次结果,以方便查看计数值//如果不执行循环,以下打印结果很可能都是相同值。for (long i = 0; i < LargeNumber; i++);Console.WriteLine("  End counting {0}  :   {1,  4:N0}ms",id, sw.Elapsed.TotalMilliseconds);}}class Program{static void Main(string[] args){MyDownloadString ds = new MyDownloadString();ds.DoRun();Console.ReadKey();}}

输出结果:

Starting call 1 : 6 ms
Starting call 2 : 237 ms
End counting 1 : 287ms
End counting 2 : 342ms
Call 1 completed: 384ms
End counting 3 : 394ms
End counting 4 : 440ms
Chars in https://www.baidu.com/ :9269
Call 2 completed: 925ms
Chars in http://www.illustractedcsharp.com :5164

由输出结果可知,程序执行到 DownloadStringTaskAsync 方法时,程序则以异步调用的方式进行。这样可以执行 DownloadStringTaskAsync 的同时,又可以执行下一行代码。

但是,最后两行代码,输出的参数从 t1 改为 t1.Result (从 t2 改为 t2.Result),由于Result 为 Task<int> 类型的,所以这两行代码需要等待 DownloadStringTaskAsync执行完毕后,返回其值才能被输出。如果该方法没有执行完毕,则阻塞并等待期值到来。

以上例子使用了异步调用,但是没有开辟新线程。是因为程序主线程异步调用了 DownloadStringTaskAsync 告诉系统它想要获取资源后,然后继续做自己的事情了。如果中间过程中,在后台系统请求网络得出结果后,会告诉主线程并把结果返回给它,它就停止手上的工作继续处理这个事情,处理完后再继续执行之前手上的工作。

请添加图片描述

由以上两个示例的输出结果可知,如果方法里有需要等待的代码块,那么该方法为同步方法时就会比作为异步方法时,需要耗费的时间就比较长。
(不使用异步示例中,该方法执行的整个过程所耗费的时间为3,323ms;而使用异步后,需要时间为925ms。主要差距的原因就在于,同步方法等待资源时,就会停止手上的工作,直到有结果返回时,才能继续工作。而异步方法等待资源的同时,还继续处理其他事情。)

二、async/await 特性的结构

同步方法: 如果某一个程序调用某个方法,并在等待方法执行所有处理后才继续执行。
异步方法: 在完成其所有方法之前就返回到调用方法。
特性:

  • 调用方法: 该方法调用异步方法,然后在异步方法执行其任务的时候继续执行(可能在相同的线程上,也可能在不同的线程上)。
  • 异步方法: 该方法异步执行其工作,然后立即返回到调用方法。
  • awaite 表达式: 用于异步方法内部,指明需要异步执行的任务。一个异步方法可以包含任意多个 await 表达式,不过如果一个都不包含的话编译器会发出警告。(大概警告:如果不使用 awaite 表达式,则会视为同步执行。)

三、async/await 特性的整体结构

//调用方法
static void Main()
{
Task<int> value DoAsyncStuff.CalculateSumAsync(5,6);
}//异步方法
staic class DoAsyncStuff
{
public static async Task<int> CalculateSumAsync(int i1,int i2)
{
int sum = await TaskEx.Run(() => GetSum(i1,i2));
return sum;
}
}

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

相关文章

电信光纤入户 itv 路由器设置

原本没有办法同时上网 看 itv的问题解决了 主要是要将路由器的dhcp,dmz功能打开 再将itv机顶盒的ip绑定dmz就ok

路由器WAN口IP显示为10、100、172开头,网络被电信联通等运营商做了NAT转发

摘要&#xff1a;路由器WAN口IP显示为10、100、172开头&#xff0c;网络被电信联通等运营商做了NAT转发...路由器WAN口IP显示为10、100、172开头的解决方法方法一&#xff1a;找电信&#xff08;10000号&#xff09;或者联通&#xff08;10010&#xff09;投诉&#xff0c;报故…

三网运营商移动联通电信话费余额查询接口-携号转网识别查询/号码归属地查询-携号转网API接口

三网话费余额查询接口&#xff0c;余额实时更新&#xff0c;非缓存&#xff0c;准确率极高。 携号转网的基本概念&#xff1a; 携号转网&#xff0c;也称作号码携带、移机不改号&#xff0c;也就是说一家电信运营商的用户&#xff0c;无需改变自己的手机号码&#xff0c;就能…

电话号码134开头的是联通,移动还是电信的?

134的号码开头的是移动的号码。联通的号段目前有:130、131、132、155、156,以及3G专用号段186、185,另还有无线上网卡号段145。.............................................

195号段是哪个运营商,195号段是正规移动卡吗?

195号段平时大家很少见到&#xff0c;那么&#xff0c;195号段是哪个运营商的&#xff0c;是正规运营商的号码吗&#xff1f;接下来我们一块来看一下。 ​ 195号段是哪个运营商&#xff0c;根据工信部分配&#xff0c;目前三大运营商的号段有&#xff1a; 中国移动拥有号段为…

jyr路由器虚拟服务器,免费路由JCG JYR-N495设置上网教程具体讲解

在前面我们介绍了免费路由JCG JYR-N495的申领教程&#xff0c;对于拿到路由器的用户来说&#xff0c;必然会关心如何设置路由器的问题&#xff0c;毕竟我们买路由器的目的就是用来上网的。 JCG JYR-N495路由器的外观设计时尚靓丽&#xff0c;采用的三天线设计&#xff0c;最高速…

电信号码段分配

大家都知道以前电信移动邮政还没有分家阿&#xff0c;邮电资源是邮电部&#xff08;现信息产业部&#xff09;统一调度的。在分配号段的时候&#xff0c;做了一些细致的规划&#xff0c;大体是这样&#xff1a; 10开头&#xff0c;电信服务号码&#xff0c;如103国际半自动挂号…

IP地址分类/IP地址10开头和172开头和192开头的区别

IP地址分类/IP地址10开头和172开头和192开头的区别/判断是否同一网段(A、B、C三类地址) IP地址分类/IP地址10开头和172开头和192开头的区别/判断是否同一网段 简单来说在公司或企业内部看到的就基本都是内网IP&#xff0c;ABC三类IP地址里的常见IP段。 每个IP地址都包含两部分&…

最新电信,网通路由表(200701日更新)

说明&#xff1a; ROS2.9.27用的网通,电信路由脚本 操作方式&#xff1a; 添加脚本方式请&#xff0c;将你的正确的电信或网通的网关&#xff0c;使用用编辑-替换掉脚本里的“网关”&#xff0c;然后打开winbox&#xff0c;点击Terminal&#xff08;控制终端&#xff…

HG8240电信光猫禁用TR069之修改配置法

昨天下午家里宽带突然断掉了。 用telnet方法检查了一下&#xff0c;发现光猫&#xff08;华为HG8240&#xff09;的telecomadmin密码被改掉了。 找回密码后&#xff0c;进入光猫&#xff0c;发现原来破解后设定的桥接模式又被改回路由模式了。[怒]&#xff01;可恶的电信远程…

携号转网查询接口API,手机号码归属地及运营商查询接口

携号转网实时手机号归属地及运营商查询接口API 可以使用以下http地址免费测试&#xff08;请求号码需更换&#xff09;&#xff1a; https://gw.qxt800.com/qxt_test?mobile13972565391 携号转网的基本概念&#xff1a; 携号转网&#xff0c;也称作号码携带、移机不改号&a…

电信网关改造无线打印服务器,电信天翼网关路由改桥接流程

大家好&#xff0c;好多网友要求我发一份网关路由改桥接的流程&#xff0c;由于平日工作太忙&#xff0c;更新点有慢&#xff0c;以后会多多分享平日工作中碰到的一些关于网络的各种问题。 路由改桥接首先准备以下两样。 1.网关一台(不管是四口还是二口都可以) 2.光猫超级密码&…

怎么分辨CN2 GIA,CN2 GT,CTG,163直连,国际线路?

怎么分辨海外服务器线路?海外服务器不像大陆服务器&#xff0c;不用纠结线路的选择&#xff0c;海外服务器线路众多&#xff0c;选择不同线路对于海外服务器的性能也有影响&#xff0c;比较关键的是很多用户都不太明白怎么分辨海外服务器的CN2(CN2 GT/CN2 GIA)、CTG、优化直连…

android 短信:电信运营商给你的号码可能是+86开头

源码中的注意点即&#xff1a;电信运营商给你的号码可能是86开头的&#xff0c;这个时候去与通讯录中库中的数据匹配&#xff0c;如果不做模糊匹配是不行的&#xff0c;而一些号码更是有‘-’在数字中间。 /*** This service essentially plays the role of a "worker thr…

中国移动、中国联通、中国电信号码网段大全

中国移动134&#xff0c;135&#xff0c;136&#xff0c;137&#xff0c;138&#xff0c;139&#xff0c; 150&#xff0c;151&#xff0c;152&#xff0c;154&#xff0c;157&#xff0c;158&#xff0c;159 187, 188(TD-SCDMA), 147 中国联通130&a…

(转)路由器WAN口IP显示为10、100、172开头,网络被电信联通等运营商做了NAT转发

转自&#xff1a;http://www.ekingcn.com/school/pcfaq_1658_202.html 1、表现形式&#xff1a; 路由器拨号获得的公网IP变成了一个以100开头的IP&#xff08;或者是10、172开头&#xff09;&#xff0c;而打开www.ip138.com查询却又是另外一个IP&#xff0c;将100开头的这个I…

HG2821T-U电信光猫修改SSID去掉ChinaNet

大家使用天翼的光猫有一个痛点,就是WIFI的名字是ChinaNet-XXX,这里我们肯定是我的光猫我做主! 于是2023年1月2日,我花了近半天的时间去攻克这个问题。 我尝试过以下方法: 1.直接登录进行修改成自己的MyWIFI(为例),保存后依然是原来的那样。 2.拿到超级管理员账号,保存后提示 …

课程17:菜单管理功能实现

🚀前言 本文是《.Net Core从零学习搭建权限管理系统》教程专栏的课程(点击链接,跳转到专栏主页,欢迎订阅,持续更新…) 专栏介绍:以实战为线索,基于.Net 7 + REST + Vue、前后端分离,不依赖任何第三方框架,从零一步一步讲解权限管理系统搭建。 专栏适用于人群:We…

Python 循环与判断(详解)

❄️作者介绍&#xff1a;奇妙的大歪❄️ &#x1f380;个人名言&#xff1a;但行前路&#xff0c;不负韶华&#xff01;&#x1f380; &#x1f43d;个人简介&#xff1a;云计算网络运维专业人员&#x1f43d; 前言 在Python中&#xff0c;循环语句有两个&#xff0c;一个是fo…

OPC是什么及OPC简介

opc既不是硬件也不是软件。OPC是一种通讯规范&#xff0c;OPC基金会组织规定的一套规范&#xff0c;按照这个规范去把程序写出来&#xff0c;包括一个OPC服务器程序和一个OPC客户端程序&#xff0c;只要是按规范写的&#xff0c;不管是谁写的&#xff0c;就能保证OPC服务器能被…
最新文章