首页 > 其他分享 >.Net Core 真异步假异步

.Net Core 真异步假异步

时间:2023-09-14 11:49:12浏览次数:41  
标签:异步 Task Core 线程 IO Net 回调 CPU

异步的回调

通过以上介绍,我们一定要记住一个知识点:异步需要回调机制。异步操作之所以能在执行结果完成之后继续执行下面程序完全归功于回调,这也是所有异步场景的核心所在,前到js的异步回调,后到cpu内核空间copy数据到用户空间完成通知 等等异步场景,回调无处不在。说道回调大部分语言都是注册一个回调函数,比如js会把回调的方法注册到执行的队列,c#会把回调注册到IOCP。这里延伸一下,在很多系统里,很多IO网络模型其实是属于同步范畴的,比如多路复用技术,真正异步非阻塞的推荐windows下的IOCP。

作者:架构师
链接:https://www.zhihu.com/question/408359907/answer/1369927257
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

真异步是没有专用线程等待的。

在整个过程中,一个关键的结论是没有线程是专门用于运行任务的。虽然工作是在某些上下文中执行的(也就是说,操作系统必须将数据传递给设备驱动程序并响应中断),但是没有专门用于等待来自请求的数据返回的线程。这允许系统处理更大数量的工作,而不是等待一些I/O调用完成。

原理解析

回忆《计算机组成原理》《操作系统》等课程里,我们知道从硬件层面上而言,目前的几乎所有的外部设备的IO都是异步操作,因为IO设备相对于CPU来说非常慢,工业界不会傻到让CPU一直干等着。一般来讲,CPU将数据先提供给IO设备然后去干别的事情,IO设备在处理完毕后向CPU发送中断请求,CPU再回来处理后事;这个特征在高级语言的层面上也有保留,不同语言中的个异步方法,通常都包含开始、回调这对双子星。

因此,高级语言层面上的异步IO操作正是贴合具体硬件实现的、高效率的IO,一个线程只需要处理启动、回调这两条工作就可以完成一个IO操作;而同步IO操作是为了提供更简单的调用而提供的(想想,如果简单的一个Hello World也需要用异步回调那么将会非常不友好),作为代价,一个线程在启动和回调之间处于等待的阻塞状态。

消息模型是如何解决同步IO必须等待IO操作这一问题的呢?当遇到IO操作时,代码只负责发出IO请求,不等待IO结果,然后直接结束本轮消息处理.
    进入下一轮消息处理过程。当IO操作完成后,将收到一条“IO完成”的消息,处理该消息时就可以直接获取IO操作结果。
    (处理过程:会开启监视线程负责处理-> 任务的启动与运行完成后的回调【一个线程可以处理多个请求】)

在“发出IO请求”到收到“IO完成”的这段时间里,同步IO模型下,主线程只能挂起,但异步IO模型下,主线程并没有休息,而是在消息循环中继续处理其他消息。
     .这样,在异步IO模型下,一个线程就可以同时处理多个IO请求,并且没有切换线程的操作。对于大多数IO密集型的应用程序,使用异步IO将大大提升系统的多任务处理能力。
     

总结

虽然我们可以包装同步IO方法使其同样可以通过await来达到不阻塞调用的效果,但是它和原生的异步IO方法具有本质上的区别,在于同步IO终究还是会阻塞线程池里的线程,而异步IO则不会。从提高吞吐量的角度而言,await一个包装起来的同步IO并不能享受本质的提升。

C# 异步陷阱(Task.Run)

看一个简单的例子
public async Task<string> MyTaskAsync(Uri address) 
{
    return await Task.Run(() =>
    {
        using (var client = new WebClient()) 
        {
            return client.DownloadString(address);
        }
    });
}
乍一眼看这个函数似乎很正常,用一个Task包裹一个耗时的WebClient.DownloadString函数。但是我们需要问一下自己:

WebClient.DownloadString 是CPU密集型,还是IO密集型
在Task.Run所在的托管线程里,是阻塞的还是非阻塞的
答案很明确:IO密集型,并且仍然是阻塞的,那么这意味着什么:我们只是换了一个地方阻塞,也就是类似于拆东墙补西墙,这样的代码确实可以使UI不再卡顿,但实际上对于性能的可拓展并没有什么好处。

public async Task<string> MyTaskAsync(Uri address)
{
    using (var client = new HttpClient())
    {
        return await client.GetStringAsync(address);
    }
}

异步底层原理(真异步是贴合具体底层硬件实现的)

https://blog.csdn.net/WuLex/article/details/123334063

异步分为两类 compute-base 和 IO-base。compute-base就是计算密集型,只要是.net基本类库提供的异步函数基本都是IO-base Task(微软官方文档是这样要求)。其实这样要求是有道理的:对于compute-base异步,比较容易封装;再者,这样的异步是不能大规模的并发的。如果16个线程cpu,同时并发16个这样的异步操作就是上限了;如果再多,反而会有害!

https://www.jb51.net/article/207090.htm

了解 .NET 的默认 TaskScheduler 和线程池(ThreadPool)设置,避免让 Task.Run 的性能急剧降低

https://blog.walterlv.com/post/default-task-scheduler-and-thread-pool.html

ASP.NET Core 最佳做法 | Microsoft Learn

微软文档

多线程简便写法

await Task.WhenAll(strings.Select(s => Task.Run(() => DoSomething(s))));
{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "ConnectionStrings": {
    "DbConnection": ""
  },
  "CBI360_JST": "server=192.168.11.238;user id=cbi360-jst;password=cbi#^)jst2018;database=CBI360_JST_CJR",
  "Mongodb": "mongodb://root:[email protected]:3717,dds-bp172db9e1d2e7d42944.mongodb.rds.aliyuncs.com:3717/admin?replicaSet=mgset-5242623",
  "SplitCount": 4,
  "SplitIndex": 1,
  "IsEndProcedure": false,
  "MinId": 24,
  "MaxId": 22371145
}
//20292168      20295017       20297867

server=121.43.37.188;user id=cbi360;password=Icb)^#3g4B!;database=HttpReports;

标签:异步,Task,Core,线程,IO,Net,回调,CPU
From: https://www.cnblogs.com/kkbk/p/17702096.html

相关文章

  • NetBenchmarkDotNet性能测试
    案例usingBenchmarkDotNet.Attributes;usingBenchmarkDotNetDemo.Model;usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Runtime.InteropServices;usingSystem.Text;usingSystem.Threading.Tasks;namespaceBenchmarkDotNetDemo......
  • 【HMS Core】推送自分类问题总结
    【关键字】推送、自分类权益 【问题背景】为了给用户提供更好的消息通知体验,从2023年9月15日开始,华为推送服务将对应用发送的本地通知频次及分类进行灰度管控。所以,最近收到了很多开发者关于自分类权益申请的问题,下面就来和大家一起分享一下 【问题描述与解答】1、如何申......
  • 在dva.js里面发送异步action
    在dva.js的effects里面不能使用setTimeout,会报错。得使用redux-saga的delay才行(注:dva.js内置了redux-saga)。如下,这样才能延时。 ......
  • 在Linux上使用netstat命令查证DDOS攻击的方法
    服务器出现缓慢的状况可能由很多事情导致,比如错误的配置,脚本和差的硬件。但是有时候它可能因为有人对你的服务器用DoS或者DDoS进行洪水攻击。DoS攻击或者DDoS攻击是试图让机器或者网络资源不可用的攻击。这种攻击的攻击目标网站或者服务通常是托管在高防服务器比如银行,信用卡支......
  • 《Docker与Kubernetes容器运维实战》简介
    #好书推荐##好书奇遇季#《Docker与Kubernetes容器运维实战》已经出版。本书帮助读者系统掌握Docker与K8s运维技能。 本书内容 本书分两部分系统介绍Docker与Kubernetes的运维技术。(1)Docker部分包括:全面认识Docker、初步体验Docker、Docker基本管理、Docker仓库、数据管理、......
  • ASP.NET MVC 入门
    https://learn.microsoft.com/zh-cn/aspnet/mvc/overview/getting-started/1、在 “开始”页上,选择“ 新建项目”。在“新建项目”对话框中,选择左侧的“VisualC#”类别,然后选择“Web”,然后选择“ASP.NETWeb应用程序”(.NETFramework) 项目模板。将项目命名为“MvcMovie......
  • docker 尝试把.netcore项目打成镜像
    添加国内镜像https://blog.csdn.net/qq_44797987/article/details/112681224生成Dockerfile文件打开VisualStudio右键Web项目,添加docker支持执行命令验证......
  • .net core(微服务学习)-使用 AgileConfig轻量配置中心
    由于之前项目维护的时候有多个API服务,发布时候又做了高可用多主机均衡负载,环境又有多套,当部署新代码的时候如果有新增配置项需要修改N个环境和服务器实属折磨人    我们知道每个.netcore中都有一个appsettings.json的配置文件,由于之前项目有3个环境,一共有4台主机,每个主......
  • 关于AD原理图中的Floating Net Label错误
    编译之后提示如下:直接双击错误跳转这是说标签浮空,没有连接到导线上这里将导线和电阻重新连接,就解决了报错还有另外一种常见的错误如下:这是标签没有连接到导线上,放大原理图并选中标签,结果如下标签左下角有个十字,必须将它放到导线上,放完之后即可解决问题(如果不好调整可以设置一下栅格......
  • VDSR-Accurate Image Super-Resolution Using Very Deep Convolutional Networks阅读
    AccurateImageSuper-ResolutionUsingVeryDeepConvolutionalNetworks(VDSR)阅读笔记(22.10.07)使用深度卷积网络的精确图像超分辨率摘要:使用一个非常深的卷积神经网络,灵感来源于VGG-Net。本文发现,网络深度增加可以显著提高准确性。本文模型最终使用了20个权重层。通过在深度网......