有的时候,我们可能会发现有些异步方法没有关键字async,程序同样能够正常运行。
了解这个之前,我们需要知道async函数的缺点;
- 异步方法是一个类(具体需要通过反编译工具看源代码),运行效率没有普通方法高。因为类的创建包含其他成员属性的声明,会消耗很多额外的资源。
- 可能会占用非常多的线程。
了解到特点以后,在某些情况下,我们可以省略掉async关键字。
string r1 = await ReadFileAsync(1);
Console.WriteLine(r1);
string r2 = await ReadFileAsync2(2);
Console.WriteLine(r2);
// 有"async"标注
async Task<string> ReadFileAsync(int num)
{
switch (num)
{
case 1:
return await File.ReadAllTextAsync("G:/1.txt");
case 2:
return await File.ReadAllTextAsync("G:/2.txt");
default:
throw new ArgumentException("num invalid");
}
}
// 无"async"标注
Task<string> ReadFileAsync2(int num)
{
switch (num)
{
case 1:
return File.ReadAllTextAsync("G:/1.txt");
case 2:
return File.ReadAllTextAsync("G:/2.txt");
default:
throw new ArgumentException("num invalid");
}
}
运行结果:
在上例中,ReadFileAsync2()函数没有关键字async,同样没有问题。该函数体的File.ReadAllTextAsync()前省略了await关键字,函数同样没有async关键字。只甩手Task,不“拆完了再装”。反编译上面的代码:只是普通的方法调用。优点:运行效率更高,不会造成线程浪费。
返回值为Task的不一定都要标注async,标注async只是让我们可以更方便的await而已。
如果一个异步方法只是对别的异步方法调用的转发,并没有太多复杂的逻辑(比如等待A的结果,再调用B;把A调用的返回值拿到内部做一些处理再返回),那么就可以去掉async关键字。(只对异步方法的返回值转发,不做其他任何处理。)
换句话说,就是此种情况只能应用于异步函数没有其他额外的业务逻辑时,只是简单的将异步的返回值返回给调用者。