技术交流QQ群【JAVA,.NET,BigData,AI】:170933152

  为什么需要异步,异步对可能起阻止作用的活动(例如,应用程序访问 Web 时)至关重要。 对 Web 资源的访问有时很慢或会延迟。 如果此类活动在同步过程中受阻,则整个应用程序必须等待。 在异步过程中,应用程序可继续执行不依赖 Web 资源的其他工作,直至潜在阻止任务完成。

  本节将一步一步带领大家理解async和await。

  期间会有

  Hello World,原理介绍,异步会提高程序的运行速度吗,async和await,MVC中的异步Action,以及线程中常涉及到的线程安全和信号量,以及微软提供的异步API

  推荐先看后顶,学的更快!

Hello World

1

2

3

4

5

6

7

8

9

10

11

12

13

14

static void Main(string[] args)

{

    new Thread(Test) { IsBackground = false }.Start();      //.Net 在1.0的时候,就已经提供最基本的API.

    ThreadPool.QueueUserWorkItem(o => Test());              //线程池中取空闲线程执行委托(方法)

    Task.Run((Action)Test);                                 //.Net 4.0以上可用

    Console.WriteLine("Main Thread");

    Console.ReadLine();

}

static void Test()

{

    Thread.Sleep(1000);

    Console.WriteLine("Hello World");

}

  

原理

  其实不管是Task,ThreadPool,本质最终都是Thread。只不过微软帮我们在简化线程控制的复杂度。

  线程池是CLR中事先定义好的一些线程。Task取的线程池,只不过在语法上,可以非常方便取返回值。

异步会提高程序的运行速度吗

  多线程会提高程序的效率,不会提高运行速度。

  这就好比这一个任务让前台花1个小时。前台完成10分钟的时候

  打电话给经理,让他安排一个人来干30分钟(new Thread()),他干剩下的20分钟。(创建线程,需要时间,内存资源)

  或者从旁边空闲的同事中(ThreadPool 或 Task),拉一个人过来干30分钟。他干剩下的20分钟。(需要的时间少,资源本来就存在)

  从上看出,异步会让一份任务时间变长。资源消耗更多。但是可以让前台(UI线程)空闲下来,听从领导(用户)指挥。

async和await只是一个标记

  首先看个Demo,

1

2

3

4

5

6

7

8

9

10

11

static void Main(string[] args)

{

    Task.Run(() =>                                          //异步开始执行

    {

        Thread.Sleep(1000);                                 //异步执行一些任务

        Console.WriteLine("Hello World");                   //异步执行完成标记

    });

    Thread.Sleep(1100);                                     //主线程在执行一些任务

    Console.WriteLine("Main Thread");                       //主线程完成标记

    Console.ReadLine();

}

  发现执行结果是:

  这个很正常。但是我们希望先执行主线程完成标记,不改动主线程和Task的任务情况下,如何处理?

使用await和async

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

static void Main(string[] args)

{

    Say();                             //由于Main不能使用async标记

    Console.ReadLine();

}

private async static void Say()

{

    var t = TestAsync();

    Thread.Sleep(1100);                                     //主线程在执行一些任务

    Console.WriteLine("Main Thread");                       //主线程完成标记

    Console.WriteLine(await t);                             //await 主线程等待取异步返回结果

}

static async Task<string> TestAsync()

{

    return await Task.Run(() =>

    {

        Thread.Sleep(1000);                                 //异步执行一些任务

        return "Hello World";                               //异步执行完成标记

    });

}

  1.凡是使用await关键字的方法,都必须打上async标记。

  2.async表示方法内有异步方法,调用async方法,会立刻另起线程执行。

  3.await只是显示等待线程结束。await表示等待异步方法执行完,并取返回值。

MVC中的异步Action

  既然多线程不能提高运行速度,而且每次请求Asp.net程序都是发起一个新的线程,为什么还要用多线程让其“降速”?

  为了提高网站的吞吐量。

  在MVC中,如果采用异步Action,则会像下面情况执行。

  1.请求到达IIS,IIS应用程序池分配一个worker线程用来响应请求。

  2.worker线程,执行异步操作,调用CLR线程池线程处理。

  3.释放worker线程,响应其他请求。

  4.异步操作执行完,w3wp(应用程序池进程)再次分配一个worker线程继续响应。

  上述使用场景中,会获取两次worker 线程,这两次获取的线程可能相同,也可能会不同。如果有比较耗时的任务,非常建议把同步请求转换为异步。

线程安全和信号量

  先举个线程不安全的例子。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

static void Main(string[] args)

{

    Task.Run((Action)Test);

    Task.Run((Action)Test);

    Console.ReadLine();

}

private static void Test()

{

    if (!IsComplete)

    {

        //todo other

        Thread.Sleep(500);

        Console.WriteLine("执行完成");

        IsComplete = true;

    }

}

public static bool IsComplete { getset; }

  上面的执行结果,这就是线程不安全。(多线程访问同一段代码 产生不确定结果。)

  

如何解决,涉及到线程锁的概念。线程锁会让多线程访问的时候,一次只允许一个线程进入。

线程锁例子

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

private static readonly object lockObj = new object();

        public static bool IsComplete { getset; }

        static void Main(string[] args)

        {

            Task.Run((Action)Test);

            Task.Run((Action)Test);

            Console.ReadLine();

        }

        private static void Test()

        {

            lock (lockObj)                              //锁住的必须是引用类型。由于在静态方法中,则锁住静态引用类型。

            {

                if (!IsComplete)

                {

                    //todo other

                    Thread.Sleep(500);

                    Console.WriteLine("执行完成");

                    IsComplete = true;

                }

            }

        }

  

信号量

  线程锁的技术使一块代码只能一个线程进入。信号量的存在,则是让同一块代码指定多个线程进入。

信号量(SemaphoreSlim)例子

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

static readonly SemaphoreSlim slim = new SemaphoreSlim(2);

        static void Main(string[] args)

        {

            for (int i = 0; i < 5; i++)

            {

                ThreadPool.QueueUserWorkItem(Test, i);

            }

            Console.ReadLine();

        }

        private async static void Test(object i)

        {

            Console.WriteLine("准备执行" + i);

            await slim.WaitAsync();

            Console.WriteLine("开始执行" + i);

            //todo other

            await Task.Delay(1000);

            Console.WriteLine("执行结束" + i);

            slim.Release();

        }

上面执行结果

从 .NET Framework 4.5 和 Windows 运行时中列出的 API 包含支持异步编程的方法。

应用程序区域

包含异步方法的受支持的 API

Web 访问

HttpClient,SyndicationClient

使用文件

StorageFile、StreamWriter、StreamReader、XmlReader

使用图像

MediaCapture、BitmapEncoder、BitmapDecoder

WCF 编程

同步和异步操作

C#.Net工作笔记003---异步编程async await相关推荐

  1. [C#] 谈谈异步编程async await

    [C#] 谈谈异步编程async await 转载于:https://www.cnblogs.com/macT/p/9288112.html

  2. async js 返回值_JS异步编程 | Async / Await / Generator 实现原理解析

    async/await实现 在多个回调依赖的场景中,尽管Promise通过链式调用取代了回调嵌套,但过多的链式调用可读性仍然不佳,流程控制也不方便,ES7 提出的async 函数,终于让 JS 对于异 ...

  3. Python异步编程Async/Await

    python 从3.5开始从语言层面提供了新的异步编程语法. import asyncioasync def hello():print("hello the world")r = ...

  4. C#.Net工作笔记003---异步编程async await_在开发中的使用经验_随时更新

    技术交流QQ群[JAVA,C++,Python,.NET,BigData,AI]:170933152 private async void test(){ TestClient client =new ...

  5. C#中的异步编程(Async)

    文章目录 C#中的异步编程(Async) 前言 示例代码 C#中的异步编程(Async) 前言 所谓的异步,就是指代码在运行的过程中,不会发生阻塞,例如我们玩游戏的时候,游戏在下载资源或者在加载本地资 ...

  6. 现代化程序开发笔记(11)——异步编程杂谈

    本系列文章以我的个人博客的搭建为线索(GitHub 仓库:Evian-Zhang/evian-blog),记录我在现代化程序设计中的一些笔记.在这篇文章中,我将以我的理解从头开始梳理一遍异步编程. 从 ...

  7. C#中的异步编程--探索await与async关键字的奥妙之处,原来理解和使用异步编程可以这么简单

    前言 await与async是C#5.0推出的新语法,关于await与async有很多文章讲解.但看完后有没有这样一种感觉,感觉这东西像是不错,但好像就是看不太懂,也不清楚该怎么使用.虽然偶有接触,但 ...

  8. Java8实战笔记--组合异步编程

    一.Future 初衷是对将来某个时刻会发生的结果进行建模. 想象成这样的场景:你拿了一袋子衣 服到你中意的干洗店去洗.干洗店的员工会给你张发票,告诉你什么时候你的衣服会洗好(这就 是一个Future ...

  9. Flutter异步编程async与await的基本使用

    题记 -- 执剑天涯,从你的点滴积累开始,所及之处,必精益求精,即是折腾每一天. ** 你可能需要 CSDN 网易云课堂教程 掘金 EDU学院教程 知乎 Flutter系列文章 异步编程常用于网络请求 ...

最新文章

  1. PowerShell收发TCP消息包
  2. CCNA重点难点:生成树配置
  3. boost::log::dynamic_type_dispatcher用法的测试程序
  4. asp.net(C#)写SQL语句技巧
  5. 阿里云刘伟光:金融核心系统将步入分布式智能化的时代
  6. redis核心技术与实战(二)缓存应用篇
  7. 19-mysql-约束
  8. 【Webpack5 配置分包加载 多文件js/css打包 】
  9. paypal如何支付欧元_做印度最好的第三方四方支付网关-在线业务源码服务wefreepay一网打尽...
  10. Java获取http和https协议返回的json数据
  11. 《LabVIEW FPGA开发宝典》第9章:利用树莓派Linux RT+FPGA PCIe实现国产化RIO
  12. 大学学计算机考试大一,大学计算机基础大一考试必备题库[1].pdf
  13. 软件测试 _ 基础知识
  14. MySQL学习笔记第二周(一)
  15. 设置 CSDN 皮肤的方法,修改成自己喜欢的皮肤
  16. WRF官网案例运行01
  17. VS2005编译器选项
  18. Python多进程读图提取特征存npy
  19. 网络共享存储器巴法罗BUFFALO的LS-WXL/E出现EM模式的解决方案
  20. SQL Server错误18456,window身份验证登录失败解决办法

热门文章

  1. python-opencv使用摄像头
  2. 吴恩达深度学习4.4笔记_Convolutional Neural Networks_人脸识别和神经风格转换
  3. [雪峰磁针石博客]大数据Hadoop工具python教程2-python访问HDFS
  4. 浏览器执行机制探究,图解最直观
  5. SinoBBD亮相全球云计算大会 彰显一体化云力量
  6. 实现前端页面跳转的几种方式
  7. 日期推算处理.sql
  8. zabbix-自定义监控项
  9. nodejs学习文档(一) 认识node.js
  10. Re-Order Buffer