理解async和await的基础用法

0 下载量 21 浏览量 更新于2024-08-31 收藏 341KB PDF 举报
"异步和等待的入门基础知识" 在编程中,`async` 和 `await` 关键字是用于实现异步编程的重要工具,尤其是在 .NET 框架中。它们帮助开发者编写非阻塞代码,提高应用程序的性能,尤其是在处理I/O密集型任务时,如网络请求、文件读写等。 `async` 关键字用于定义一个异步方法。当在方法签名前加上 `async`,这个方法就会返回一个 `Task` 或 `Task<T>` 对象,表示异步操作的状态。异步方法内部可以包含 `await` 关键字,用于等待一个异步操作完成,而不会阻塞当前线程。 在示例中,`SumPageSizes` 方法是同步版本的,它逐个下载 `Uri` 并累加内容长度。这种方式在处理多个网络请求时,由于每个请求都是顺序执行的,所以总耗时将是所有请求时间之和,就像描述中的例子那样,如果有5个请求分别耗时1到5秒,总耗时会是15秒。 然而,如果我们使用 `async` 和 `await` 实现异步版本,可以显著减少总耗时。在 `AsyncDemo` 类中,可以将 `SumPageSizes` 方法改造为异步版本: ```csharp public async Task<int> SumPageSizesAsync(IList<Uri> uris) { int total = 0; foreach (var uri in uris) { Console.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId}: 开始下载 {uri} {DateTime.Now}"); var data = await Task.Run(() => new WebClient().DownloadData(uri)); total += data.Length; Console.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId}: 下载完成 {uri}, 长度 {data.Length} {DateTime.Now}"); } Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}: 总长度 {total} {DateTime.Now}"); return total; } ``` 在这个异步版本中,`await Task.Run(() => ...)` 会创建一个新的 `Task`,并将 `DownloadData` 操作放在新线程上执行,允许主线程在等待时继续执行其他工作。这样,多个网络请求可以并行进行,大大减少了总耗时。 `Main` 函数调用异步方法的方式也需要改变,使用 `await` 关键字等待异步操作完成: ```csharp public static async Task Main() { List<Uri> uris = new List<Uri>(); // 添加 Uri 列表... int sum = await AsyncDemo.SumPageSizesAsync(uris); Console.WriteLine($"总长度(异步):{sum} {DateTime.Now}"); } ``` 通过这种方式,即使在处理大量网络请求时,应用也可以保持响应性,避免了长时间阻塞主线程。异步编程是现代应用开发中的重要概念,尤其对于提升用户体验和系统效率至关重要。正确理解和使用 `async` 和 `await` 可以帮助开发者编写出更加高效、非阻塞的代码。