async ,await使用方法详解
以前工作中用的框架都是.NET Framework 4.0,最近因为一些原因开始接触ASP .NET Core 才接触到 async+ await。
简直是发现新大陆啊,刚开始也在网上各大博客平台寻找资料资料,大家的说法都有较大的偏差。只能我自己动手探索新大陆了,废话不多说代码先上。
首先我们先创建两个异步方法First_Async和Second_Async以及一个同步方法Other,用来模拟我们现实中的业务场景:
static void Main(string[] args)
{
Console.WriteLine("开始调用Main方法" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
First_Async();
Console.WriteLine("结束调用Main方法" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
Console.ReadLine();
}
private static async Task<string> First_Async()
{
Other(); //同步方法
return await Second_Async(); //异步方法
}
public static string Other()
{
Console.WriteLine("开始调用Other方法" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
Thread.Sleep(5000); //阻塞线程5s
Console.WriteLine("结束调用Other方法" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
return "";
}
public static async Task<string> Second_Async()
{
Console.WriteLine("开始调用Second_Async方法" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
await Task.Run(() =>
{
Thread.Sleep(5000);
});
Console.WriteLine("结束调用Second_Async方法" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
return "";
}
OJBK,方法写好了,我们来测试看看运行的结果:
细心的小伙伴们可能已经发现问题了,说好的异步方法呢,怎么跟想象中的不一样(手动狗头)。在我们定义的异步方法First_Async内先等待了Other的响应才会返回main方法。以下是微软官方的解释:
await 运算符应用于异步方法中的任务,在方法的执行中插入挂起点,直到所等待的任务完成。 任务表示正在进行的工作。
await 表达式不阻止正在执行它的线程。 而是使编译器将剩下的异步方法注册为等待任务的延续任务。 控制权随后会返回给异步方法的调用方。 任务完成时,它会调用其延续任务,异步方法的执行会在暂停的位置处恢复。
大概意思就是说就算方法内加了async后,我们创建的异步方法也不会都进行异步处理。带async修饰的异步方法是不会自动生成子线程进行异步处理业务逻辑的,真正的异步处理逻辑是我们的 await Task.Run(() =>{Thread.Sleep(5000); });。而await的作用是告诉上一级的方法,我这里有一个异步的代码块需要处理,你自己去干其他事情吧,后面的事情都不用你管了。然后就把主线程的控制权交回给上一级方法。
老规矩,上代码,我们根据上面总结的内容巧妙的修改一下我们的程序如下:
private static async Task<string> First_Async()
{
string s = await Second_Async(); //异步方法
Other(); //同步方法
return s;
}
运行结果如下:
不出所料,主线程没有再等待First_Async的响应,直接继续往下执行。至此新大陆被我们占领了,或者说新大陆的某个小海滩被我们占领了。(手动滑稽)