awit
使用非异步方法调用可异步方法(内含嵌套异步)
效果图:
private static void AsyncTest()
{
Func<Task<string>> Fun1 = () =>
{
Thread.Sleep(4000);
console.WriteLine("Fun1 Open");
return Task.Run(()=>
{
Thread.Sleep(2000);
Console.WriteLine("Fun1 Run Open");
Console.WriteLine("..............................");
Thread.Sleep(5000);
Console.WriteLine("..............................");
Console.WriteLine("Fun1 Run Close");
return "Fun1";
});
};
Func<Task<string>> Fun2 = async () =>
{
Thread.Sleep(1000);
Console.WriteLine("Fun2 Open");
var str2 = await Fun1();
Thread.Sleep(1000);
Console.WriteLine("Fun1 Result "+ str2);
Console.WriteLine("Fun2 Close");
return "Fun2";
};
Console.WriteLine("Asyn Open");
var str = Fun2();
Console.WriteLine("Fun2 Result " + str);
Console.WriteLine("Asyn Close");
}
情景:
- 两个异步程序Fun2/Fun1
- Fun2使用(await)调用Fun1
- Fun2不使用异步调用
分析:
- 主线程执行过程中,遇到异步Fun2,执行同步过程,进入函数Fun2
- 函数Fun2执行过程中,遇到异步Fun1,执行异步过程await,进入Fun1
- 函数Fun1执行过程中,遇到异步时间Run,开启异步
- 主函数不等待异步,Fun1无返回值,输出Task对象
- 函数Fun2等待Fun1结果,再执行await后的语句
结论:
- 封装后的异步调用,如果被同步调用,应该使用void/Task无返回值方式
- await后的语句,相当于异步调用后的回调方法,写法更美观
使用await调用异步方法(嵌套异步)
代码:
var str = await Fun2();
在上文代码中Fun2函数前面加上await
效果图:
分析:
- 主线程执行过程中,遇到异步Fun2,执行异步过程await,进入函数Fun2
- 函数Fun2执行过程中,遇到异步Fun1,执行异步过程await,进入Fun1
- 函数Fun1执行过程中,遇到异步时间Run,开启异步
- 函数Fun2等待Fun1结果,再执行await后的语句
- 主函数等待Fun2结果,再执行await后的语句
结论:
- 要想达到嵌套异步的回调效果,每一个异步环节都要使用await标记分割
使用await调用异步方法(连续await)
效果图代码:
Fun1添加参数p做区分,Fun2添加并行的await
Func<string, Task<string>> Fun1 = (string p) =>
{
Thread.Sleep(4000);
Console.WriteLine("Fun1 Open " + p);
return Task.Run(()=>
{
Thread.Sleep(2000);
Console.WriteLine("Fun1 Run Open " + p);
Console.WriteLine("..............................");
Thread.Sleep(5000);
Console.WriteLine("..............................");
Console.WriteLine("Fun1 Run Close " + p);
return "Fun1 " + p;
});
};
Func<Task<string>> Fun2 = async () =>
{
Thread.Sleep(1000);
Console.WriteLine("Fun2 Open");
var str2 = await Fun1("No.1");
Thread.Sleep(1000);
Console.WriteLine("Fun1 Result "+ str2);
str2 = await Fun1("No.2");
Thread.Sleep(1000);
Console.WriteLine("Fun1 Result " + str2);
Console.WriteLine("Fun2 Close");
return "Fun2";
};
结论:
注意:
await异步回调的边界,是async所标记的函数的边界。其async函数内部的循环/判断等语句,都要服从与await的等待与回调过程。
相关阅读
异步编程 101:Python async await发展简史
本文参考了:How the heck does async/await work in Python 3.5? PEP 380: Syntax for Delegating to a Subgenerator yield 和 yi
using System; using System.Data.OleDb; namespace ConsoleApplication { class Program { static void Main(
第一步:首先从Visual Studio中的Nuget包管理中搜索下载 Log4Net dll文件 如下图: 第二步:打开配置文件 WinFrom就是 App.config We
C#中ref和out关键字的应用以及区别。refref的定义ref 的使用outout的定义:来自MSDNout的用法ref和out的区别Stack Overflow的解释:
转载于:https://www.cnblogs.com/lbonet/p/10215723.html