传统的异步编程方式很复杂,直到 C# 5 引入了 async 编程模式。
.NET 内置的异步方法
async 和 await 关键字
async 和 await 是 C# 异步编程的核心,由它们定义的方法称为异步方法。
异步方法示例:
// Three things to note in the signature:// - The method has an async modifier.// - The return type is Task or Task<T>.// 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;}
什么是异步方法
方法签名包括 async 修饰符
约定方法名以 Async 为后缀
返回类型为以下几种之一
- Task
- Task
- void
- 方法内部至少包含一句 await 表达式:
string urlContents = await getStringTask;- await 表达式的意思是:方法在此处需要等待异步操作完成后才能继续向下执行。同时方法将被挂起,控制流返回给方法的调用者
异步编程的核心就是 Task 和 Task
在 C# 中一个 Task 对象可以看作一个需要继续执行的操作,一个 Task
I/O 绑定异步操作示例:从 Web Service 下载数据
private readonly HttpClient _httpClient = new HttpClient();downloadButton.Clicked += async (o, e) =>{// This line will yield control to the UI as the request// from the web service is happening.//// The UI thread is now free to perform other work.var stringData = await _httpClient.GetStringAsync(URL);DoSomethingWithData(stringData);};
CPU 绑定异步操作示例:执行计算
使用 Task.Run 来启动一个后台线程用于执行 CPU 绑定的操作。
private DamageResult CalculateDamageDone(){// Code omitted://// Does an expensive calculation and returns// the result of that calculation.}calculateButton.Clicked += async (o, e) =>{// This line will yield control to the UI while CalculateDamageDone()// performs its work. The UI thread is free to perform other work.var damageResult = await Task.Run(() => CalculateDamageDone());DisplayDamage(damageResult);};
.NET 类库内置的异步方法
通过 Async 后缀和返回类型为 Task(Task)来识别内置的异步方法。
网络操作相关的:
HttpClient:发送 HTTP 请求,接收 HTTP 响应
WebClient:收发数据
I/O 操作相关的:
StreamWrite
StreamReader
XmlReader
