C# 异步操做 async await

在编程的过程当中,咱们会遇到不少须要异步操做的场景。好比要下载一个文件,若是使用同步的方式进行下载,那么UI操做就会被卡住,这时最好可以使用异步的方式进行下载。在C#中,很早就开始支持异步的操做了,只不过早期的方法写起来有些麻烦。到了C# 5.0的时候,直接添加了两个关键字:async 和 await,这下对异步操做的支持可谓是达到了完美。下面咱们就通用一个简单的 demo 看一下它们的基本用法。python

下载一个文件

咱们先看看用同步的方式下载一个文件:程序员

private void btnOldDownload_Click(object sender, EventArgs e)
{
    using(WebClient wc = new WebClient())
    {
        // 咱们尝试去下载 python 的安装包。
        wc.DownloadFile("https://www.python.org/ftp/python/3.5.2/python-3.5.2-amd64.exe", "python.exe");
    }
    lbMessage.Text = "下载完成。";
}

在执行 DownloadFile 方法的过程当中,UI线程被卡死,整个的下载过程当中应用程序都处于没响应的状态。这固然是不能接受的,因此咱们应该使用下面的异步方式进行文件的下载。编程

异步下载文件

咱们先看一下使用早期的异步代码去下载文件:异步

private void OldAsyncDownload_Click(object sender, EventArgs e)
{
    using (WebClient wc = new WebClient())
    {
        // 咱们尝试去下载 python 的安装包。
        // 下载完成时会有事件通知。
        wc.DownloadFileCompleted += Wc_DownloadFileCompleted;
        wc.DownloadFileAsync(new Uri("https://www.python.org/ftp/python/3.5.2/python-3.5.2-amd64.exe"), "python.exe");
    }
}
private void Wc_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
    lbMessage.Text = "下载完成。";
}

好吧,事情变得稍微有点复杂了。一个简单的下载逻辑竟然被分隔到了两个方法中!在第一个方法中挂载 DownloadFileCompleted 事件,而后启动下载。下载完成后经过 DownloadFileCompleted 事件处理函数进行通知。若是您可以习惯于这样的写法,其实C# 早期提供的异步编程接口已经足够用了,由于这也正是异步操做真正的实现方式。async

可是,做为程序员,咱们是不会知足的,永远不会…异步编程

async await 方式

在C# 5.0 中引入了 async 和 await 关键字,它们使得异步操做的实现更加简单、容易!函数

private async void btnMyAsync_Click(object sender, EventArgs e)
{
    using (WebClient wc = new WebClient())
    {
        // 咱们尝试去下载 python 的安装包。
        Task task = wc.DownloadFileTaskAsync("https://www.python.org/ftp/python/3.5.2/python-3.5.2-amd64.exe", "python.exe");
        // 能够在这里执行代码。
        await task;
    }
    lbMessage.Text = "下载完成。";
}

注意代码中 async 和 await 关键字的位置,这样代码就是以异步方式去执行下载逻辑,整个过程当中UI 操做不会被阻塞掉。是否是很神奇呢?spa

这段代码最大的魔力在于它和同步下载文件的代码几乎相同!每一个 人都喜欢写顺序执行的代码,这样的代码逻辑也最清晰。async 和 await 的最大优点就是把人脑感受简单的代码转换为真正的异步操做逻辑。线程

相关文章
相关标签/搜索