同步的阻塞  JS异步  这个JS也好!!!!

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("");
    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);
}

人各有命,上天注定,有人天生为王,有人落草为寇。脚下的路,如果不是你自己的选择,那么旅程的终点在哪,也没人知道。你会走到哪,会遇到谁,都不一定。