Async_Await 一些概念性的东西

在伯乐在线看到的一篇关于async_await的文章,总结得挺好
1.0 “async”这个关键字让我们能够在方法内部使用“await”关键字,我们并没有在线程池的线程中运行这个方法,只是激活了await关键字(并管理方法结果)。
2.0 异步方法在开始执行时,和其它任何方法都是一样的。也就是说,在遇到“await”关键字(或者抛出异常)之前,方法都是同步运行的。
3.0 “await”关键字可以让事情异步运行。await会检查可等待操作是否已经结束,如果可等待操作已经完成,方法就会继续运行。
如果“await”发现可等待操作还没有完成,那么就会异步地执行。它会告诉可执行操作,在完成之后,继续执行方法剩余的部分,然后从异步方法返回。
过些时候,当可执行操作完成后,它会执行异步方法的剩余部分。如果你在等待一个内置的可等待操作(例如Task),那么异步方法的剩余部分会在“await”返回之前的“上下文”中执行。
我喜欢将“await”当做“异步等待”。也就是说,异步方法会暂停,直到可等待操作结束(因此它在等待),但是这种异步等待导致调用方在获取结果之前都可以不等待await之后的代码执行!
4.0 上面提到的上下文是什么呢?
简单的回答是:
            如果你是在UI线程上,那么它就是UI上下文。
            如果你是在响应一个ASP.NET的请求,那么它就是ASP.NET的请求上下文。
            否则,通常它是一个线程池上下文。
复杂的回答:
如果 SynchronizationContext.Current 不为空,那么它是当前的 SynchronizationContext(UI上下文和ASP.NET请求上下文都是 SynchronizationContext 上下文)。否则,它是当前的 TaskScheduler(TaskScheduler.Default是线程池上下文)。
比如:
            private async void DownloadFileButton_Click(object sender, EventArgs e)
        {
            // 既然我们使用异步的方式等待,那么UI线程就不会被文件下载所阻塞。
            await DownloadFileAsync(fileNameTextBox.Text);

            // 既然我们从UI上下文中恢复,我们就可以直接访问UI元素。而无需调用Invoke为控件赋值
            resultTextBox.Text = "File downloaded!";
        }
5.0 避免上下文
通过调用 ConfigureAwait 方法并传入false的方式,来告诉“等待者”不要捕捉当前的上下文。
        private async Task DownloadFileAsync(string fileName)
        {
            // 使用HttpClient或者其他任何方式来下载文件内容
            var fileContents = await DownloadFileContentsAsync(fileName).ConfigureAwait(false);

            // 请注意由于ConfigureAwait(false),我们并没有在原来的上下文中。
            // 相反,我们运行在线程池上。

            // 将文件内容写入到外部的磁盘文件中。
            await WriteToDiskAsync(fileName, fileContents).ConfigureAwait(false);

            // 这里第二次调用ConfigureAwait(false)并不是*必需*的,但这是一个最佳实践。
        }
6.0 参考文章
 https://blogs.msdn.microsoft.com/pfxteam/2012/04/12/asyncawait-faq/
 https://blogs.msdn.microsoft.com/pfxteam/2011/01/13/await-anything/
原文地址:https://www.cnblogs.com/entclark/p/8232938.html