一直捋不清楚用Task.Run异步的执行关系,网上找的些说明写得也有点复杂,所以自己做实验测一下。
直接上代码
这个是加await
private static void TestFun()
{
Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")} Test start!");
MainTask();
Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")} Test End !");
} private static async Task MainTask()
{
Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")} MainTask Start !");
Thread.Sleep(2000);
//await or not
await Task.Run(() =>
{
Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")} Subtask Start !");
Thread.Sleep(2000);
Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")} Subtask End !");
});
Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")} MainTask End !");
}
执行结果
这里TestFun调用async异步方法Maintask,2s后遇到await,马上回去执行TestFun中后面的操作“Test End”,同时await里的Subtask也开始执行,并且Subtask完成后才显示“MainTask end”。
再去掉await
private static void TestFun()
{
Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")} Test start!");
MainTask();
Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")} Test End !");
} private static async Task MainTask()
{
Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")} MainTask Start !");
Thread.Sleep(2000);
//await or not
Task.Run(() =>
{
Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")} Subtask Start !");
Thread.Sleep(2000);
Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")} Subtask End !");
});
Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")} MainTask End !");
Thread.Sleep(1000);
}
结果
这里顺序就不一样了,进入MainTask 2s后,执行Subtask的Task,并且开始执行Subtask之后的内容,再之后才跳出MainTask显示“End”。
为了便于理解,我在“MainTask End”下面多sleep了1s,为了区分上一个测例因为遇到await Task跳出的情况。
简单总觉一下:
调用async异步方法的线程,遇到await,马上回去继续执行后面的操作,而async异步方法里面,则是执行完任务,再继续执行await关键字后面的内容,相当于await关键字后面内容,是在回调中完成。
最后回顾一下,写的基本和其他人一样难懂,但自己是捋清楚了,也不亏,哈哈。