c# async和await 用法(阻塞与不阻塞)

看示例吧:

 1 void PagePaint()
 2 {
 3     Console.WriteLine("Paint Start");
 4     Paint();
 5     Console.WriteLine("Paint End");
 6 }
 7
 8 void Paint()
 9 {
10     Rendering("Header");
11     Rendering(RequestBody());
12     Rendering("Footer");
13 }
14
15 string RequestBody()
16 {
17     Thread.Sleep(1000);
18     return "Body";
19 }

假设有这么个页面布局的方法,依次对头部、主体和底部进行渲染,头部和底部是固定的内容,而主体需要额外请求。
这里用Sleep模拟网络延时,Rendering方法其实也就是对Console.WriteLine的简单封装而已。。。
PagePaint运行过后,结果是这样的:

Paint Start
Header
Body
Footer
Paint End

挺正常的结果,但是Header渲染完以后页面就阻塞了,这个时候用户没法对Header进行操作。
于是就进行这样的修正:

 1 async void Paint()
 2 {
 3     Rendering("Header");
 4     Rendering(await RequestBody());
 5     Rendering("Footer");
 6 }
 7
 8 async Task<string> RequestBody()
 9 {
10     return await Task.Run(() =>
11     {
12         Thread.Sleep(1000);
13         return "Body";
14     });
15 }

运行结果变成了这样:

Paint Start
Header
Paint End
Body
Footer

这样就能在Header出现之后不阻塞主线程了。

不过呢,Footer一直都得等到Body渲染完成后才能被渲染,这个逻辑现在看来还没问题,因为底部要相对于主体进行布局。
然而我这时候又想给页面加一个广告,而且是fixed定位的那种,管啥头部主体想盖住就盖住,你们在哪它不管。
比如这样写:

1 async void Paint()
2 {
3     Rendering(await RequestAds());
4     Rendering("Header");
5     Rendering(await RequestBody());
6     Rendering("Footer");
7 }

出现了很严重的问题,头部都得等广告加载好了才能渲染,这样显然是不对的。
所以应该改成这样:

 1 async void Paint()
 2 {
 3     PaintAds();
 4     Rendering("Header");
 5     Rendering(await RequestBody());
 6     Rendering("Footer");
 7 }
 8
 9 async void PaintAds()
10 {
11     string ads = await Task.Run(() =>
12     {
13         Thread.Sleep(1000);
14         return "Ads";
15     });
16     Rendering(ads);
17 }

这样的运行结果就算令人满意了:

Paint Start
Header
Paint End
Ads
Body
Footer

原文地址:https://www.cnblogs.com/bile/p/9389813.html

时间: 2024-10-11 21:10:46

c# async和await 用法(阻塞与不阻塞)的相关文章

ES6中的promise、async、await用法详解

<!DOCTYPE html> <html> <head> <title>Promise.async.await</title> </head> <body> <script type="text/javascript"> //promise用法(返回异步方法返回的数据,resolve获取数据成功后调用的方法, reject获取数据失败后调用的方法) //第一种写法 var p = new

浅谈async函数await用法

今天状态不太好,睡久了懵一天. 以前只是了解过async函数,并还没有很熟练的运用过,所以先开个坑吧,以后再结合实际来更新下,可能说的有些问题希望大家指出. async和await相信大家应该不陌生,让异步处理变得更友好. 其实这玩意儿就是个Generator的语法糖,想深入学习得去看看Generator,不然你可能只停留在会用的阶段. 用法很简单,看代码吧. // 先声明一个函数,这个函数返回一个promise, 先记住哈!后面很多地方要用 function getPromise(str =

C#中async和await用法

.net 4.5中新增了async和await这一对用于异步编程的关键字. async放在方法中存在await代码的方法中,await放在调用返回Task的方法前. class Class1 { private async void DoSomething() { await Do(); } private Task Do() { return Task.Run(() => { Thread.Sleep(5000); }); } [STAThread] static void Main(stri

第十五节:深入理解async和await的作用及各种适用场景和用法

一. 同步VS异步 1.   同步 VS 异步 VS 多线程 同步方法:需要等待返回结果,才可以继续往下执行业务 异步方法:无须等待返回结果,可以继续往下执行业务 开启新线程:在主线程之外开启一个新的线程去执行业务 同步方法和异步方法的本质区别: 是否需要等待返回结果才能继续执行业务 2. 常见的异步方法(都以Async结尾) ① HttpClient类:PostAsync.PutAsync.GetAsync.DeleteAsync ② EF中DbContext类:SaveChangesAsyn

Promise和Async/Await用法整理

1.Promise 1.简介 Promise,简单来说就是一个容器,里面保存着某个未来才会结束的时间(通常是一个异步操作的结果) Promise对象的基本语法: new Promise((resolve,reject) => { //..... }); 从语法上来说,Promise是一个对象,从它可以获取异步操作的消息. 基本语法: let p = new Promise((resolve,reject) => { //... resolve('success') }); p.then(res

async和await关键字实现异步编程

async和await关键字实现异步编程 异步编程 概念 异步编程核心为异步操作,该操作一旦启动将在一段时间内完成.所谓异步,关键是实现了两点:(1)正在执行的此操作,不会阻塞原来的线程(2)一旦启动的此操作,可以继续执行其他任务.当该操作完成时,将调用回调函数来通知该操作已经结束. [注]:本人一直以为同步和异步都属于多线程的范畴,到今天才明白完全错误,异步和多线程是属于不同范畴,多线程和异步是并发的两种形式,并行处理和线程同步是多线程的两种形式,这是我当前的理解,不知是否有误,文中若有错误,

【多线程】Task ,async ,await

一. WinForm 里经常会用到多线程, 多线程的好出就不多说了,来说说多线程比较麻烦的地方 1. UI 线程与其他线程的同步,主要是 Form 和 Control 在跨线程时的使用,这里是值得注意的,因为少有不甚就会出错. 二. 常用的跨线程方法 1.  Invoke : 同步调用, 因为是同步操作,所以如果操作 UI 的方法很耗时,就不推荐了,得用 BeginInvoke. 代码: private void button1_Click(object sender, EventArgs e)

C#基础系列——异步编程初探:async和await

前言:前面有篇从应用层面上面介绍了下多线程的几种用法,有博友就说到了async, await等新语法.确实,没有异步的多线程是单调的.乏味的,async和await是出现在C#5.0之后,它的出现给了异步并行变成带来了很大的方便.异步编程涉及到的东西还是比较多,本篇还是先介绍下async和await的原理及简单实现. C#基础系列目录: C#基础系列——Linq to Xml读写xml C#基础系列——扩展方法的使用 C#基础系列——序列化效率比拼 C#基础系列——反射笔记 C#基础系列——At

Async、Await

Async.Await:net4.x新增的异步编程方式: 目的:为了简化异步程序编写 Async方式, 使用Async标记Async1为异步方法, 用Await标记GetRequestStreamAsync表示方法内需要耗时的操作. 主线程碰到await时会立即返回,继续以非阻塞形式执行主线程下面的逻辑. 当await耗时操作完成时,继续执行Async1下面的逻辑 详解:复杂 C# 5.0 Async函数的提示和技巧:复杂 谈谈异步编程async await:简单 C#基础系列--多线程的常见用