初探C#异步模式
0,环境
.Net Core6.0
1,先上代码及结果截图
// See https://aka.ms/new-console-template for more information
using System.Diagnostics;
using System.Threading;
namespace LearnAsync
{
public class Program
{
public static void Main(string[] args)
{
Stopwatch s = new();
s.Start();
Solution solution = new();
solution.DoWashingWork(); // 1
solution.DoWork(); // 2
solution.Rest();// 3
Task<int> result;
result = solution.Count(); // 4
solution.DoWork(); // 5
Console.WriteLine($"Result:{result.Result}"); // 6
s.Stop();
Console.WriteLine($"time:{s.Elapsed.TotalMilliseconds} ms");
Console.ReadKey();
}
}
public class Solution
{
public async void DoWashingWork()
{
Console.WriteLine("Start washing...");
await Task.Run(()=>Thread.Sleep(4000)); // 7
Console.WriteLine("end washing.");
}
public void DoWork()
{
Console.WriteLine("Start working...");
Thread.Sleep(1000);
Console.WriteLine("end working.");
}
public void Rest()
{
Console.WriteLine("Start resting...");
Thread.Sleep(2000);
Console.WriteLine("end resting.");
}
public async Task<int> Count()
{
Console.WriteLine("start count..");
return await Task.Run(Get); // 8
}
public int Get() //计算阶乘
{
int s = 1;
for (int i = 2; i < 15; i++)
{
s *= i;
Thread.Sleep(100); //模拟耗时
}
Console.WriteLine("end counting..");
return s;
}
}
}
*注释后面标的序号是为了便于后文叙述程序流程
运行结果:
3,流程分析及async,await关键字解释
(Main) 1
(DoWashingWork) 7
*(发现await ,一边执行await后面的任务,一边回到主线程)*
(Main) 2
(Main) 3
(Main) 4
(Count) 8
(发现await ,一边执行await后面的任务,一边回到主线程)
(Main) 5
(Main) 6
(Main)6 由于要调用(Count) 8的结果所以等待8执行完。
asnyc 是声明异步方法的关键字
asnyc声明的方法中至少要有一个await
await作用
1)其所在的方法本体等待其执行完毕(这一点和同步没区别)
2) 同时回到 调用其 的地方(本程序是Main),不等待方法执行完毕继续执行其它代码.
这样分析理论用时应该为:
1000+2000<4000
所以2,3完的时候同步的1还没结束
计算阶乘大约 100*15 = 1500ms
1000+2000+1500 =4500>4000
所以一共约4500ms 符合结果.
顺序大家可以自己跑一下验证.
3,异步模式的作用
防止程序在某些耗时的任务上阻塞而使后面不依赖此任务的其它任务不能利用等待时间完成。