异步杂记yield return
Async和Await的本质其实是“yield return”和“LINQ”的“迭代式”等待 Yield(又特)
Yield Return关键字的作用就是退出当前函数,并且会保存当前函数执行到什么地方,也就上下文。
下次执行这个函数上次跑来的代码是不会重复执行的
Yield(让出,出产,产生)
async/await本质是返回一个Task而已,而Task又是异步的(因为Task本质就是一个线程)
所以真正执行到(使用到async方法的时候)带有await的方法的时候,后台才会真正开启一个线程去执行任务。
此时主线程会等待这个Task线程直到其执行完毕(IsComplete属性为True为止)。
所以界面是不会卡顿的(因为并不会影响到UI线程)
=========================================================
//新异步,在执行await表达式前都是使用UI线程,await表达式后会启用新的线程去执行异步,直到异步执行完成并返回结果,然后再回到UI线程(据说使用了SynchronizationContext)。
//所以,await是没有阻塞UI线程的,也就不会造成界面的假死。==》可以理解为界面的卡顿是因为阻塞了UI线程,既然UI线程没有阻塞,那么界面自然不会出现卡顿的现象
Debug.WriteLine("【Debug】主线程ID:" + Thread.CurrentThread.ManagedThreadId); //System.Net.Http HttpClient http = new HttpClient(); var htmlstr = await http.GetStreamAsync("http://www.jb51.net/article/57156.htm"); StreamReader sr = new StreamReader(htmlstr, Encoding.UTF8); var str = sr.ReadToEnd(); Debug.WriteLine("【Debug】异步线程ID:" + Thread.CurrentThread.ManagedThreadId); label1.Invoke((Action)(() => { label1.Text = "新异步执行完成" + str; })); // label1.Text = "新异步执行完毕" + htmlstr;
//旧的异步模式是开启了一个新的线程去执行,不会阻塞UI线程。这点很好理解。
var request = WebRequest.Create("http://www.jb51.net/article/57156.htm"); request.BeginGetResponse(new AsyncCallback(c => { //BeginGetResponse 对网络资源进行异步操作, //如果要读取网络资源,用流的形式来展示, StreamReader sd = new StreamReader(request.GetResponse().GetResponseStream()); var str = sd.ReadToEnd(); label1.Invoke((Action)(() => { label1.Text = "旧异步执行完成" + str; })); }), null);
private void button1_Click(object sender, EventArgs e) { //因为winform始终都需要UI线程渲染界面,如果UI线程被占用则会出现“假死”状态 Debug.WriteLine("[Debug]线程ID" + Thread.CurrentThread.ManagedThreadId); var request = WebRequest.Create("https://github.com/"); request.GetResponse(); //发送请求 Debug.WriteLine("[Debug]线程ID" + Thread.CurrentThread.ManagedThreadId); label1.Text = "执行完毕"; //方法调用前和调用后线程ID都是9(也就是同一个线程) }
private void button2_Click(object sender, EventArgs e) { //APM异步编程,Asynchronous Programming Model //C#1 基于IAsynchronous 接口实现Beginxxxx 和EndXXX Debug.WriteLine("[Debug]线程ID" + Thread.CurrentThread.ManagedThreadId); //HttpWebRequest类主要利用HTTP 协议和服务器交互 //Create 里的参数是要访问的网址,一般会返回给你个信息,一般会返回XML或者json var request = WebRequest.Create("http://www.cnblogs.com/haogj/archive/2011/06/09/2076708.html"); Debug.WriteLine(request); request.BeginGetResponse(new AsyncCallback(t => //执行完成后的回掉 { var response = request.EndGetResponse(t); var stream = response.GetResponseStream(); using(StreamReader reader = new StreamReader(stream)) { StringBuilder sb = new StringBuilder(); while(!reader.EndOfStream) { var content = reader.ReadLine(); sb.Append(content); } Debug.WriteLine("[Debug]" + sb.ToString().Trim().Substring(0, 100) + "..."); Debug.WriteLine("【Debug】异步线程ID:" + Thread.CurrentThread.ManagedThreadId); label1.Invoke((Action)(() => { label1.Text = sb.ToString(); })); } }), null); Debug.WriteLine("【Debug】主线程ID:" + Thread.CurrentThread.ManagedThreadId); }
人各有命,上天注定,有人天生为王,有人落草为寇。脚下的路,如果不是你自己的选择,那么旅程的终点在哪,也没人知道。你会走到哪,会遇到谁,都不一定。