参考了一些大佬写的文章:

https://www.cnblogs.com/yilezhu/p/10555849.html这个大佬写的文章,我还是很喜欢的

https://www.cnblogs.com/mushroom/p/4575417.html

https://blog.csdn.net/dyllove98/article/details/9735955这篇文章是讨论在.NET中使用进程内COM组件时的公寓模型,以一个示例直观演示STAThread和MTAThread的作用和区别。

C#5.0,.NET Framework4.5

async/await是语法糖,本身就跟编译器提供的功能。

在winform中,是一个STAThread

在winform中使用await/async偶尔会出现一些意外,所以不建议在winform中使用await/async

  await/async关键字,在任何一个方法都可以增加async,await放在Task前面,一般成对出现,只有async是没有意义的,有警告,只有await的时候会报错,编译直接报错,await/async要么不用,要么用到底。  

  主线程调用async/await方法,主线程遇到await返回只能后续动作,await后面的代码会等着task任务完成后再继续执行,await是主线程完成的,其实就像是把await后面的代码包装成一个continue的回调动作,然后这个回调动作也可能是task线程,也可能是新的子线程,也可能是主线程。

  一个async方法,如果没有返回值,可以方法声明返回Task

 private static async Task<long> SumAsync()
{
Console.WriteLine($"SumAsync 111 start ManagedThreadId={Thread.CurrentThread.ManagedThreadId}");
long result = ; await Task.Run(() =>
{
for (int k = ; k < ; k++)
{
Console.WriteLine($"SumAsync {k} await Task.Run ManagedThreadId={Thread.CurrentThread.ManagedThreadId}");
Thread.Sleep();
}
for (long i = ; i < 999_999_999; i++)
{
result += i;
}
}); Console.WriteLine($"SumFactory 111 end ManagedThreadId={Thread.CurrentThread.ManagedThreadId}");
await Task.Run(() =>
{
for (int k = ; k < ; k++)
{
Console.WriteLine($"SumAsync {k} await Task.Run ManagedThreadId={Thread.CurrentThread.ManagedThreadId}");
Thread.Sleep();
}
for (long i = ; i < ; i++)
{
result += i;
}
}); Console.WriteLine($"SumFactory 111 end ManagedThreadId={Thread.CurrentThread.ManagedThreadId}"); await Task.Run(() =>
{
for (int k = ; k < ; k++)
{
Console.WriteLine($"SumAsync {k} await Task.Run ManagedThreadId={Thread.CurrentThread.ManagedThreadId}");
Thread.Sleep();
} for (long i = ; i < ; i++)
{
result += i;
}
}); Console.WriteLine($"SumFactory 111 end ManagedThreadId={Thread.CurrentThread.ManagedThreadId}"); return result;
}
Task<long> t = SumAsync();
Console.WriteLine($"Main Thread Task ManagedThreadId={Thread.CurrentThread.ManagedThreadId}");

有了await之后,在这个方法中,代码是按照顺序从上往下执行的,但是,为什么不直接写一个同步方法,还要写await呢?

  如果不写await的话,Task.Run()会开启一个线程,不会足额色主线程,这样在最后的结果result就是0了。

await/async能够用同步的方式编写代码,但是又是非阻塞的。

原理探究和使用建议:

 public class AwaitAsyncILSpy
{
public static void Show()
{
Console.WriteLine($"start1 {Thread.CurrentThread.ManagedThreadId.ToString("")}");
Async();
Console.WriteLine($"aaa2 {Thread.CurrentThread.ManagedThreadId.ToString("")}");
}
public static async void Async()
{
Console.WriteLine($"ddd5 {Thread.CurrentThread.ManagedThreadId.ToString("")}");
await Task.Run(() =>
{
Thread.Sleep();
Console.WriteLine($"bbb3 {Thread.CurrentThread.ManagedThreadId.ToString("")}");
});
Console.WriteLine($"ccc4 {Thread.CurrentThread.ManagedThreadId.ToString("")}");
}
}
 AwaitAsyncLibrary.AwaitAsyncILSpy.Show();
Console.WriteLine("hello word!");

这样的代码,输出的顺序是是什么?

await/async能够用同步的方式编写代码,但又是非阻塞的

async方法在编译之后会生成一个状态机(实现了IAsyncStateMachine接口)

状态机:初始化状态----执行就修改状态1-----再执行就修改状态变为0-----执行就修改状态变为1----如果出现其他状态就结束了。

就像是红绿灯那样,永远的死循环下去。

  async方法里面的逻辑其实都放在了MoveNext----主线程new一个状态机1-----主线程调用MoveNext-----指向了await之前的东西----启动Task----主线程改状态为0----回去干自己的事了-----子线程Movenext----状态又回归-1了-----再执行后续的逻辑------如果需要还可以继续循环。

AwaitAsync(异步和多线程)的更多相关文章

  1. IOS异步和多线程操作&&在sqlite3中的应用

    1,数据库I/O操作(异步) 数据库本身是存储在磁盘上.访问和修改数据库,即对磁盘进行读写,即I/O操作. 磁盘属于计算机硬件,具有DMA能力,不需要CPU干预,可以实现异步操作. I/O操作一般是消 ...

  2. C#中异步和多线程的区别

    C#中异步和多线程的区别是什么呢?异步和多线程两者都可以达到避免调用线程阻塞的目的,从而提高软件的可响应性.甚至有些时候我们就认为异步和多线程是等同的概念.但是,异步和多线程还是有一些区别的.而这些区 ...

  3. PHP中实现异步调用多线程程序代码

    本文章详细的介绍了关于PHP中实现异步调用多线程方法,下面我们以给1000个用户发送一封推荐邮件,用户输入或者导入邮件账号了提交服务器执行发送来讲述. 比如现在有一个场景,给1000个用户发送一封推荐 ...

  4. c#异步和多线程有什么区别和联系?

    异步和多线程可以说没有必然的联系,只能说异步可以通过多线程实现而已要理解这些东西,你得具备很多相关的知识,操作系统原理,编译原理等简单地来说,计算机或者说CPU执行你的代码都是顺序执行的,当前的语句没 ...

  5. 编写高质量代码改善C#程序的157个建议——建议71:区分异步和多线程应用场景

    建议71:区分异步和多线程应用场景 初学者有时候会将异步和多线程混为一谈.如果对它们之间的区别不是很清楚,很容易写出下面这样的代码: private void buttonGetPage_Click( ...

  6. C#用委托实现异步,异步与多线程的异同

    异步与多线程的区别(转) 一.异步和多线程有什么区别?其实,异步是目的,而多线程是实现这个目的的方法.异步是说,A发起一个操作后(一般都是比较耗时的操作,如果不耗时的操作就没有必要异步了),可以继续自 ...

  7. 【Java_基础】并发、并行、同步、异步、多线程的区别

    1. 并发:位于同一个处理器上的多个已开启未完成的线程,在任意一时刻系统调度只能让一个线程获得CPU资源运行,虽然这种调度机制有多种形式(大多数是以时间片轮巡为主).但无论如何,都是通过不断切换需要运 ...

  8. C#中的异步和多线程

    许多开发人员对异步代码和多线程以及它们的工作原理和使用方法都有错误的认识.在这里,你将了解这两个概念之间的区别,并使用c#实现它们. 我:"服务员,这是我第一次来这家餐厅.通常需要4个小时才 ...

  9. C#异步和多线程以及Thread、ThreadPool、Task区别和使用方法

    本文的目的是为了让大家了解什么是异步?什么是多线程?如何实现多线程?对于当前C#当中三种实现多线程的方法如何实现和使用?什么情景下选用哪一技术更好? 第一部分主要介绍在C#中异步(async/awai ...

随机推荐

  1. go语言之if语句和switch语句和循环语句

    1.if语句 package main import ( "fmt" "io/ioutil" ) func main() { //流程控制 //使用常量定义一个 ...

  2. Python 调用 ES、Solr、Phoenix

    #!/usr/bin/env python # -*- coding:utf-8 -*- # ************************************* # @Time : 2019/ ...

  3. maven中servlet报错:不识别此servlet问题的解决办法

    原因 使用maven集成的tomcat插件的时候,tomcat的lib中,自带servlet-api和jsp. 如果maven中再次导入了这两个jar,会造成jar包冲突现象. 解决办法 我们只是想编 ...

  4. SpringCloud中Feign的适配器的实现方案

    前言 最近在做微服务的项目,各个系统之间需要进行调用,然后用一个适配器来实现服务之间的feign调用,使用适配器进行统一管理. 实现方案 首先我们需要将服务的名称进行单独的配置,可以方便的进行切换和扩 ...

  5. [算法]PriorityQueue的应用

    1. 数据流中的第K大元素 题目 设计一个找到数据流中第K大元素的类(class).注意是排序后的第K大元素,不是第K个不同的元素. 你的 KthLargest 类需要一个同时接收整数 k 和整数数组 ...

  6. [转]How to enable macros in Excel 2016, 2013, and 2010

    本文转自:https://www.ablebits.com/office-addins-blog/2014/07/22/enable-macros-excel/#always-run-macros T ...

  7. 记录Android开发中遇到的坑

    1. 出现错误提示:Intel HAXM is required to run this AVD,VT-x is disabled in BIOS的解决办法. 点击SDK图标,安装Intel x86 ...

  8. fastadmin安装定时插件报错 ZipArchive::extractTo(): Permission denied

    环境linux上直接安装  如果你是在win开发号直接部署的应该是没问题  我是直接在linux安装的 这几天研了下fastadmin 想用他的定时可是在使用的时候报错   ZipArchive::e ...

  9. Python入门基础学习(时间模块,随机模块)

    Python基础学习笔记(六) time模块: 时间的三种表示方法: 1.格式化字符串 2.时间戳 用来表示和1970年的时间间隔,单位为s 3.元组 struct_time 9个元素 time的st ...

  10. ArrayList的输出以及一些问题

    //首先需要创建一个ArrayList ArrayList arr=new ArrayList(); //然后往ArrayList里面插入一些值 arr.add("a"); arr ...