浅谈Async和Await如何简化异步编程(几个实例让你彻底明白)

2019-12-30 15:22:57于海丽

引言

C#5.0中async和await两个关键字,这两个关键字简化了异步编程,之所以简化了,还是因为编译器给我们做了更多的工作,下面就具体看看编译器到底在背后帮我们做了哪些复杂的工作的。

同步代码存在的问题

对于同步的代码,大家肯定都不陌生,因为我们平常写的代码大部分都是同步的,然而同步代码却存在一个很严重的问题,例如我们向一个Web服务器发出一个请求时,如果我们发出请求的代码是同步实现的话,这时候我们的应用程序就会处于等待状态,直到收回一个响应信息为止,然而在这个等待的状态,对于用户不能操作任何的UI界面以及也没有任何的消息,如果我们试图去操作界面时,此时我们就会看到”应用程序为响应”的信息(在应用程序的窗口旁),相信大家在平常使用桌面软件或者访问web的时候,肯定都遇到过这样类似的情况的,对于这个,大家肯定会觉得看上去非常不舒服。引起这个原因正是因为代码的实现是同步实现的,所以在没有得到一个响应消息之前,界面就成了一个”卡死”状态了,所以这对于用户来说肯定是不可接受的,因为如果我要从服务器上下载一个很大的文件时,此时我们甚至不能对窗体进行关闭的操作的。为了具体说明同步代码存在的问题(造成界面开始),下面通过一个程序让大家更形象地看下问题所在:


// 单击事件
    private void btnClick_Click(object sender, EventArgs e)
    {
      this.btnClick.Enabled = false;

      long length = AccessWeb();
      this.btnClick.Enabled = true;
      // 这里可以做一些不依赖回复的操作
      OtherWork();

      this.richTextBox1.Text += String.Format("n 回复的字节长度为: {0}.rn", length);
      txbMainThreadID.Text = Thread.CurrentThread.ManagedThreadId.ToString();
    }

    private long AccessWeb()
    {
      MemoryStream content = new MemoryStream();

      // 对MSDN发起一个Web请求
      HttpWebRequest webRequest = WebRequest.Create("http://www.easck.com/zh-cn/") as HttpWebRequest;
      if (webRequest != null)
      {
        // 返回回复结果
        using (WebResponse response = webRequest.GetResponse())
        {
          using (Stream responseStream = response.GetResponseStream())
          {
            responseStream.CopyTo(content);
          }
        }
      }

      txbAsynMethodID.Text = Thread.CurrentThread.ManagedThreadId.ToString();
      return content.Length;
    }

运行程序后,当我们点击窗体的 “点击我”按钮之后,在得到服务器响应之前,我们不能对窗体进行任何的操作,包括移动窗体,关闭窗体等,具体运行结果如下:

async,await,c#,async异步编程,异步