我试图理解将 lambda 传递到执行 lambda 的异步方法的两种方法的后果。下面的示例总结了这两种方法。在第一种方法中,lambda 本身是异步的,而在第二种方法中则不是。
虽然这是一个人为的示例,但我试图确定这两种方法是否更“正确”,可以更好地处理极端情况(例如,如果 lambda 抛出异常),是否具有明显更好的性能,等等。从调用者的角度来看,这些方法在功能上是否等效?
class Program
{
static async Task Main(string[] args)
{
var result1 = await ExecuteFuncAsync(
async () =>
{
var funcResult = await Task.FromResult(false);
return funcResult;
});
var result2 = await ExecuteFuncAsync(
() =>
{
var funcResult = Task.FromResult(false);
return funcResult;
});
}
private static async Task<bool> ExecuteFuncAsync(Func<Task<bool>> func)
{
return await func();
}
}
这取决于上下文。我认为两者之间没有重大区别(在提供的示例中,一般来说 - 请参阅Stephen Cleary 的“消除异步和等待” https://blog.stephencleary.com/2016/12/eliding-async-await.html).
尽管在包装的函数是同步函数的情况下应该考虑第三种选项:
var result2 = ExecuteFuncAsync(() => Task.Run(() =>
{
var funcResult = true;
return funcResult;
}));
或者对于一些主要的测试/实验场景:
var result2 = await ExecuteFuncAsync(async () =>
{
await Task.Yield();
var funcResult = true;
return funcResult;
});
区别在于异步函数首先将控制权返回给调用者await
但前提是等待的任务尚未完成。考虑以下片段:
Console.WriteLine("First before");
var first = ExecuteFuncAsync(
async () =>
{
var funcResult = await Task.FromResult(false);
return funcResult;
});
Console.WriteLine("First before await");
await first;
Console.WriteLine("First after await");
Console.WriteLine();
Console.WriteLine("Second before");
var second = ExecuteFuncAsync(() =>
{
var funcResult = Task.FromResult(false);
return funcResult;
});
Console.WriteLine("Second before await");
await second;
Console.WriteLine("Second after await");
Console.WriteLine();
Console.WriteLine("Third before");
var third= ExecuteFuncAsync(async () =>
{
await Task.Yield();
return true;
});
Console.WriteLine("Third before await");
await third;
Console.WriteLine("Third after await");
static async Task<bool> ExecuteFuncAsync(Func<Task<bool>> func)
{
var t = func();
Console.WriteLine("Inner Before await");
await t;
Console.WriteLine("Inner After await");
return true;
}
产生以下输出:
First before
Inner Before await
Inner After await
First before await
First after await
Second before
Inner Before await
Inner After await
Second before await
Second after await
Third before
Inner Before await
Third before await
Inner After await
Third after await
请注意,对于前两种情况,外部before and afterwait 仅在内部 before 和 after 之后发生,而第三个选项具有“正确”的输出顺序。这可能是一次出价交易。在某些情况下,如果内部函数是长时间运行的函数并且调用者依赖于异步行为。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)