C#异步/等待关键字


C#中的async / await关键字提供了管理资源密集型应用程序的便捷方法,这些应用程序在前端语言(如Javascript库)中更为常见。返回Task<T>类型的方法可以使用async关键字async ,并且当在UI处理程序或服务工作流中调用这些方法时,我们可以使用方法上的await来告诉C#将控制权返回给它的调用者,直到后台工作完成了。通过对资源密集型调用产生控制,我们能够让UI更具响应性并使服务更具弹性。

asyncawait的核心是Task<T>类。当与async关键字一起使用它作为方法的返回类型时,我们指示该方法已经承诺返回T类型的对象(对于不返回任何值的方法,使用Task作为返回类型) 。

一旦遇到async方法,工作将在线程池中排队执行,而调用者将继续执行而不等待async方法的返回值。但是,在大多数情况下,我们的UI和服务依赖于从async方法返回的值:例如,当我们使用async方法查询本地数据库时,我们最终想知道查询结果是什么并对其进行操作,同步。这是使用await关键字的地方:如果在调用async方法时使用await关键字,调用者将暂停执行,直到从async方法返回结果,并且表示父方法将继续执行而不等待调用者完成。话虽如此,任何使用await关键字的方法本身都必须是async函数 - 这也是由C#编译器强制执行的,如果使用Visual Studio编写C#代码,IDE会在方法违反async-await发出警告async-await合同。

例子

  1. 将表单提交到服务器
private readonly string url = 'http://localhost:3000/api/submit';
 private readonly HttpContent formContent = new HttypContent();

 // Update the formContent object while filling up the form.

 SubmitButton.Clicked += async (object, event) =>
 {
  // When PostAsync is hit, the button control will release the UI, while the
  //   http post method is still waiting on server response.
  HttpClient httpClient = new HttpClient();
  var response = await httpClient.PostAsync(url, formContent);
  Console.WriteLine(response.StatusCode);
 }
  1. “锁存器”同步器
public async Task<int> CalcDamage(Player player)
 {
  // CPU-intense method, calculate afflicted damage done to the
  //   Boss based on the damage types, Boss stats (from static data),
  //   player stats, etc.
  // ...
 }

 public static async Task<int> CalcTotalDamage(IEnumerable<Player> group)
 {
  var totalDamage = 0;
  foreach (Player player in group)
  {
    // each of the async methods are queued in the thread-pool and move on.
    totalDamage += CalcDamage(player);
  }

  // total damage done must be calculated from all players in the group
  //   before we return the result.
  return await Task.WhenAll(totalDamage);
 }

备忘单

  • 等待:从后台异步调用中检索结果。
  • await Task.WhenAny:如果任何排队任务完成,则继续。
  • await Task.WhenAll:仅在所有排队任务完成后才继续。
  • 等待Task.Delay:在执行前保持一段时间。

更多C#教程

学习更多C#教程