当前位置 : 主页 > 网络编程 > 其它编程 >

异步编程async/await

来源:互联网 收集:自由互联 发布时间:2023-07-02
异步编程可以提高整个系统的响应速度,但不能提高单次请求的时间。服务器可以响应更多的请求,每一个请求的总时长基本是不变的。当一个请求A处理比较耗时的操作,系统就会不等
异步编程可以提高整个系统的响应速度,但不能提高单次请求的时间。服务器可以响应更多的请求,每一个请求的总时长基本是不变的。当一个请求A处理比较耗时的操作,系统就会不等这个请求A,让A

异步编程可以提高整个系统的响应速度,但不能提高单次请求的时间。

服务器可以响应更多的请求,每一个请求的总时长基本是不变的。

当一个请求A处理比较耗时的操作,系统就会不等这个请求A,让A自己处理这个耗时操作,而是直接处理下一个请求B。

等这个请求A中耗时的操作处理完了,系统再来接着处理请求A后续的功能。

Async/Await 是一个语法糖,方便写异步编程,其原理是状态机模式编程。

举了一个点菜的例子:你进一个菜馆,服务员A,来接待你到指定座位,然后你开始点菜,由于你点菜比较耗时,服务员A给了你菜单后就去服务其他客户去了。

等你好久点完菜了,然后你再叫服务员把菜单给后厨,但这时服务你的不一定是A,很可能是服务员B。

 

static async Task Main(string[] args) { Console.WriteLine("第一:"+Thread.CurrentThread.ManagedThreadId); string filePath = @"D:\GitSource\Temp\a.txt"; StringBuilder sb = new StringBuilder(); for (int i = 0; i <10000; i++) { sb.Append("Hello World!"); } Console.WriteLine("第二:" + Thread.CurrentThread.ManagedThreadId); await File.WriteAllTextAsync(filePath, sb.ToString()); Console.WriteLine("第三:" + Thread.CurrentThread.ManagedThreadId); string s = await File.ReadAllTextAsync(filePath); Console.WriteLine("第四:" + Thread.CurrentThread.ManagedThreadId); Console.WriteLine(s); Console.WriteLine("guala"); Console.WriteLine("第五:" + Thread.CurrentThread.ManagedThreadId); Console.ReadKey(); }

可以看到打印出来的线程Id是不一样的。 如果异步处理的时间比较短,也可能一样。

异步方法返回一般是Task类型(无返回值时是Task),当你用await来等时,取到的结果就是T 对象本身。类似于Task.Result

 

异步不等于多线程

方法标了Async Task就一定是异步方法,但不一定是多线程方法,比如:

Console.WriteLine("异步前:"+Thread.CurrentThread.ManagedThreadId);double result =await GetResultAsync(5);Console.WriteLine("异步后:" + Thread.CurrentThread.ManagedThreadId);Console.ReadKey();async Task GetResultAsync(int input){ Console.WriteLine("异步中:" + Thread.CurrentThread.ManagedThreadId); double result = 0; for (int i = 0; i //{ // double result = 0; // for (int i = 0; i 运行结果:

 

 如果该方法中使用Task来运行:

 

 

可以看出是真的多线程执行。

 

线程休息 ,间隔几秒再做某事,用 await Task.Delay(),不阻塞主线程,异步调用,不要用Thread.Sleep(),这个会阻塞主线程 ,影响web服务的性能 

 

异步调用时注意参数:CancellationToken ,可以传递参数,适时停止操作

static async Task Main(string[] args) { CancellationTokenSource cts = new CancellationTokenSource(); cts.CancelAfter(1000);//1秒之后取消 await GetWebSitHtml("http://www.baidu.com", 10, cts.Token); Console.ReadKey(); } async static Task GetWebSitHtml(string url,int n,CancellationToken cancellationToken) { using (HttpClient client = new HttpClient()) { for (int i = 0; i 如果调用的异步方法本身支持 CancellationToken,则记得要传递该参数给异步方法。

GetStringAsync 本身不支持 CancellationToken,可以换一个支持的

async static Task GetWebSitHtml(string url,int n,CancellationToken cancellationToken) { using (HttpClient client = new HttpClient()) { for (int i = 0; i 微软提供的这个异步方法支持 cancellationToken 参数,我们只需要接过参数传给它就行了。 这个方法里也随时停止。

 

再有一种是手动停止:比如输入q字母停止:

static async Task Main(string[] args) { CancellationTokenSource cts = new CancellationTokenSource(); GetWebSitHtml("http://www.baidu.com", 100, cts.Token); while (Console.ReadLine() !="q") { } cts.Cancel(); Console.ReadKey(); } async static Task GetWebSitHtml(string url,int n,CancellationToken cancellationToken) { using (HttpClient client = new HttpClient()) { for (int i = 0; i   

杨中科讲异步编程,将的很透彻,耐心看完 .NET 6教程,.Net Core 2022视频教程,杨中科主讲_哔哩哔哩_bilibili

上一篇:求教根据不同文件类型,自动切换缩紧
下一篇:没有了
网友评论