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

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. API收藏

    1.百度图片api get 方法$word = '北海';//要搜索的词$num = 3;//要搜索的数量$url = 'https://image.baidu.com/search/acjson?t ...

  2. C sharp #004# 进度条与Timer

    饮水思源:金老师的自学网站 C#实现进度条异常简单,因为所有东西都已经封装好了. 只需要简单的拖拽: 写两行代码就完工了: private void timer1_Tick(object sender ...

  3. SpringCloud的入门学习之概念理解、Zuul路由网关

    1.Zuul路由网关是什么? 答:Zuul包含了对请求的路由和过滤两个最主要的功能,其中路由功能负责将外部请求转发到具体的微服务实例上,是实现外部访问统一入口的基础而过滤器功能则负责对请求的处理过程进 ...

  4. [Spring cloud 一步步实现广告系统] 3. 网关路由

    Zuul(Router and Filter) WIKI: 传送门 作用 认证,鉴权(Authentication/Security) 预判(Insights) 压力测试(Stress Testing ...

  5. SSM整合2(springMVC+mybatis)

    客户在浏览器端会提交一些参数到服务器端,比如用户的登录等,就会传username 和 password过来,springmvc则通过参数绑定组件将请求参数的内容进行数据转换,然后将转换后的值覆给con ...

  6. golang 处理 json 结构体

    首先 我们来看一下这个json 字串 { "resp": { ", "respMsg": "成功", "app" ...

  7. Python小练习:StringIO和BytesIO读写操作的小思考

    from io import StringIO; f = StringIO(); f.write('Hello World'); s = f.readline(); print s; 上面这种方法&q ...

  8. Vulnhub DC-1靶机渗透学习

    前言 之前听说过这个叫Vulnhub DC-1的靶机,所以想拿来玩玩学习,结果整个过程都是看着别人的writeup走下来的,学艺不精,不过这个过程也认识到,学会了很多东西. 所以才想写点东西,记录一下 ...

  9. OSI参考模型总结

    OSI(Open System Interconnect),即开放式系统互联. 一般都叫OSI参考模型,是ISO(国际标准化组织)组织在1985年研究的网络互连模型.下面我们将一层一层的看OSI协议. ...

  10. [20191108]内核参数tcp_keepalive与sqlnet.ora expire_time的一些总结.txt

    [20191108]内核参数tcp_keepalive与sqlnet.ora expire_time的一些总结.txt --//前几天在做12c DCD SQLNET.EXPIRE_TIME相关测试时 ...