在使用.Net 异步编程模型开发时,Async和await关键字可以帮助我们轻松的完成异步开发,让代码看起来和同步编程一致,保持清晰的逻辑过程。
Async 修饰符可将方法、lambda 表达式或匿名方法指定为异步方法。
根据约定,异步方法请方法名最后加上Async来表示这是一个异步方法(非必须,但请尽量遵守)。
示例代码(一个异步方法):
/// <summary>
/// 输出指定网页大小
/// </summary>
/// <param name="url">网页地址</param>
/// <param name="num">获取次数</param>
/// <returns></returns>
private static async Task GetHtmlLengthAsync(string url, int num)
{
using HttpClient httpClient = new HttpClient();
for (int i = 0; i < num; i++)
{
string html = await httpClient.GetStringAsync(url);
Console.WriteLine($"{html.Length}-{i + 1}次,线程ID-{Thread.CurrentThread.ManagedThreadId}");
}
}
await 运算符会等待异步方法执行完成后,返回执行结果并将结果解析为指定返回类型(如果有)。
await 运算符使用注意:
1.await 不会阻止执行异步方法的线程。
2.await 不会创建新的线程(线程由线程池提供)。
3.不能在lock语句中使用await。
4.不能在同步函数内使用await,await必须在异步方法中使用。
示例代码:
public async static Task AsyncMain()
{
Console.WriteLine($"开始获取网页大小,线程ID-{Thread.CurrentThread.ManagedThreadId}");
await GetHtmlLengthAsync("https://www.baidu.com", 10);
Console.WriteLine($"获取网页大小完成,线程ID-{Thread.CurrentThread.ManagedThreadId}");
Console.ReadLine();
}
输出结果:
测试下没有await时,异步方法如何执行,将AsyncMain方法中的await运算符去掉后代码如下:
public async static Task AsyncMain()
{
Console.WriteLine($"开始获取网页大小,线程ID-{Thread.CurrentThread.ManagedThreadId}");
GetHtmlLengthAsync("https://www.baidu.com", 10);
Console.WriteLine($"获取网页大小完成,线程ID-{Thread.CurrentThread.ManagedThreadId}");
Console.ReadLine();
}
输出结果:
从执行结果来看,不使用await运算符时,线程1不会等待异步方法执行完就会继续向下执行。