C# 的 await / async 关键字

更新日期: 2018-09-01 阅读次数: 17942 分类: CSharp

await 关键字,在 async 方法中使用,当主线程调用 async 方法,遇到 await 关键字时,就会挂起。继续执行其他的任务,而不会因为这些耗时操作阻塞其他任务。

例如,要在按钮的点击事件中,进行 HTTP 异步请求

private async void Button_Click_Async(object sender, RoutedEventArgs e)
{  
       var client = new HttpClient();  
       var uri = new Uri(Uri.EscapeUriString(url));
       byte[] urlContents = await client.GetByteArrayAsync(uri);
       Console.WriteLine($"{url}: {urlContents.Length/2:N0} characters");  
}  

await 与新开线程的区别。

在代码编写上,要比多线程编程要简单很多。

Asynchrony proves especially valuable for applications that access the UI thread because all UI-related activity usually shares one thread. If any process is blocked in a synchronous application, all are blocked. Your application stops responding, and you might conclude that it has failed when instead it's just waiting.

定义一个 async 函数需要注意的问题

// Three things to note in the signature:  
//  - The method has an async modifier.   
//  - The return type is Task or Task<T>. (See "Return Types" section.)  
//    Here, it is Task<int> because the return statement returns an integer.  
//  - The method name ends in "Async."  
async Task<int> AccessTheWebAsync()  
{   
    // You need to add a reference to System.Net.Http to declare client.  
    HttpClient client = new HttpClient();  

    // GetStringAsync returns a Task<string>. That means that when you await the  
    // task you'll get a string (urlContents).  
    Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");  

    // You can do work here that doesn't rely on the string from GetStringAsync.  
    DoIndependentWork();  

    // The await operator suspends AccessTheWebAsync.  
    //  - AccessTheWebAsync can't continue until getStringTask is complete.  
    //  - Meanwhile, control returns to the caller of AccessTheWebAsync.  
    //  - Control resumes here when getStringTask is complete.   
    //  - The await operator then retrieves the string result from getStringTask.  
    string urlContents = await getStringTask;  

    // The return statement specifies an integer result.  
    // Any methods that are awaiting AccessTheWebAsync retrieve the length value.  
    return urlContents.Length;  
}  

如何识别函数库中哪些 API 支持异步 Async。

  • 名字后缀为 Async
  • 返回的类型为 Task 或者 Task。例如 Task

You might be wondering where to find methods such as GetStringAsync that support async programming. The .NET Framework 4.5 or higher and .NET Core contain many members that work with async and await. You can recognize them by the "Async" suffix that’s appended to the member name, and by their return type of Task or Task. For example, the System.IO.Stream class contains methods such as CopyToAsync, ReadAsync, and WriteAsync alongside the synchronous methods CopyTo, Read, and Write.

Task MainPage.Button_Click_Async(object, RoutedEventArgs)' has the wrong return type

如下点击事件的代码报错

private async Task Button_Click_Async(object sender, RoutedEventArgs e)

修改为

private async void Button_Click_Async(object sender, RoutedEventArgs e)

之后,编译成功。

原因是,只有当你自己编写一个需要 await 的函数时,才需要加 Task。在点击事件的响应函数中无需这样。

关于作者 🌱

我是来自山东烟台的一名开发者,有敢兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式

谈笑风生

c# 配合vs2017 效率挺高的,用起来也很流畅。。

大象

域名不错。。。