AwaitAsync(异步和多线程)

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

http://www.javashuo.com/article/p-wkkdrrxi-ck.html这个大佬写的文章,我仍是很喜欢的async

http://www.javashuo.com/article/p-akgxzveo-hx.htmlspa

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

 

C#5.0,.NET Framework4.5线程

async/await是语法糖,自己就跟编译器提供的功能。3d

在winform中,是一个STAThreadcode

 

 

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

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

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

  一个async方法,若是没有返回值,能够方法声明返回Task

private static async Task<long> SumAsync() { Console.WriteLine($"SumAsync 111 start ManagedThreadId={Thread.CurrentThread.ManagedThreadId}"); long result = 0; await Task.Run(() => { for (int k = 0; k < 10; k++) { Console.WriteLine($"SumAsync {k} await Task.Run ManagedThreadId={Thread.CurrentThread.ManagedThreadId}"); Thread.Sleep(1000); } for (long i = 0; i < 999_999_999; i++) { result += i; } }); Console.WriteLine($"SumFactory 111 end ManagedThreadId={Thread.CurrentThread.ManagedThreadId}"); await Task.Run(() => { for (int k = 0; k < 10; k++) { Console.WriteLine($"SumAsync {k} await Task.Run ManagedThreadId={Thread.CurrentThread.ManagedThreadId}"); Thread.Sleep(1000); } for (long i = 0; i < 999999999; i++) { result += i; } }); Console.WriteLine($"SumFactory 111 end ManagedThreadId={Thread.CurrentThread.ManagedThreadId}"); await Task.Run(() => { for (int k = 0; k < 10; k++) { Console.WriteLine($"SumAsync {k} await Task.Run ManagedThreadId={Thread.CurrentThread.ManagedThreadId}"); Thread.Sleep(1000); } for (long i = 0; i < 999999999; 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("00")}"); Async(); Console.WriteLine($"aaa2 {Thread.CurrentThread.ManagedThreadId.ToString("00")}"); } public static async void Async() { Console.WriteLine($"ddd5 {Thread.CurrentThread.ManagedThreadId.ToString("00")}"); await Task.Run(() => { Thread.Sleep(500); Console.WriteLine($"bbb3 {Thread.CurrentThread.ManagedThreadId.ToString("00")}"); }); Console.WriteLine($"ccc4 {Thread.CurrentThread.ManagedThreadId.ToString("00")}"); } }
 AwaitAsyncLibrary.AwaitAsyncILSpy.Show(); Console.WriteLine("hello word!");

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

 

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

 

 

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

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

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

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

相关文章
相关标签/搜索