C#中的async
/ await
关键字提供了管理资源密集型应用程序的便捷方法,这些应用程序在前端语言(如Javascript库)中更为常见。返回Task<T>
类型的方法可以使用async
关键字async
,并且当在UI处理程序或服务工作流中调用这些方法时,我们可以使用方法上的await
来告诉C#将控制权返回给它的调用者,直到后台工作完成了。通过对资源密集型调用产生控制,我们能够让UI更具响应性并使服务更具弹性。
async
和await
的核心是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
合同。
例子
- 将表单提交到服务器
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);
}
- “锁存器”同步器
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#教程