传递 lambda 或异步 lambda 来执行?有权衡吗? [复制]

2024-03-26

我试图理解将 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(使用前将#替换为@)

传递 lambda 或异步 lambda 来执行?有权衡吗? [复制] 的相关文章

随机推荐

  • 将 FFTW 链接到 Android NDK 应用程序

    我目前正在编写一个流派分类应用程序 作为我计算机工程的最后一年项目 我最初用 C 语言编写了特征提取代码 实现 FFTW 现在我需要通过 NDK 在 Android 上实现它 这是我的第一个 NDK 项目 所以我仍在掌握一些东西 但我已经根
  • 如何在linux中包含python模块?

    我发现了这个 xgoogle python 模块http github com pkrumins xgoogle http github com pkrumins xgoogle 很有意思 我到底应该如何在 Linux 中包含或安装这些文件
  • 单个模块/函数等有超过 1 个文档字符串吗?

    我正在使用 python 3 1 是否可以为单个模块或函数创建超过 1 个文档字符串 我正在创建一个程序 并且打算拥有多个文档字符串 每个文档字符串都有一个类别 我打算向其他人提供该程序 以便他们可以使用它 并且为了让程序员和非程序员都轻松
  • 如何在 Quickblox iOS SDK 中检查会话是否有效或过期?

    我知道 任何会话在向 Quickblox 服务器发出最后一个请求 2 小时前发出 后都会过期 当我创建会话时 我能够找到 QBBaseModule sharedModule tokenExpirationDate但我不确定它是如何工作的以及
  • PHP:通过引用可变长度参数列表?

    是否可以创建一个 PHP 函数 该函数采用可变数量的参数 所有参数均通过引用 它对通过引用接收值数组的函数和将其参数包装在对象中的函数没有帮助 因为我正在研究函数组合和参数绑定 也不要考虑调用时间传递引用 那东西根本不应该存在 PHP 5
  • 如何在laravel中使用shift-jis编码导出csv文件?

    我在用laravel excel https laravel excel com 导出 csv 文件 要导出 代码如下 return Excel download new Export results header test csv Exp
  • 为什么我的关系表会抛出 OutOfMemoryError?

    我正在使用 iReport 构建 jaspersoft 报告 并使用 Fishbowl 作为我的 DBMS 我构建了我的表 在 iReport 中显示我的表是相关的 但由于某种原因它会抛出错误并且不会运行 应该很简单 我正在输入邮政编码 日
  • 使用 PathCollections 的图例

    我正在使用集合绘制圆圈组 但无法生成三个类别的图例 我想 第 1 类 红色圆圈 类别 2 蓝色圆圈 第 3 类 黄色圆圈 import matplotlib import matplotlib pyplot as plt from matp
  • 在我的应用程序中包含 jpeg 插件

    我制作了一个加载 jpeg 文件的 Qt GUI 应用程序 在我安装了 QtSDK 4 7 3 的开发系统 Win7 上 它可以工作 当我将应用程序和一些必需的 dll 如 QtGui4 dll 等 移动到另一个未安装 QtSDK 的系统时
  • 将多个数据帧合并为一个扩展帧

    我有一个数据帧列表 其中每个帧都包含单个系统的相同类型的测量值 例如 system1 file cumSize cumloadTime query1 1 data data1 dat 100000 158 1000 0 4333333 2
  • 动态加载和动态链接的区别?

    例程在被调用之前不会被加载 所有例程都以可重定位加载格式保存在磁盘上 主程序被加载到内存中并被执行 这称为动态链接 为什么这称为动态链接 不应该是动态加载吗 因为在动态加载中调用例程之前不会加载 而在动态链接中 链接会推迟到执行时 此答案假
  • 使用 python 登录 quora

    我尝试使用 python 登录 quora 但它给了我以下错误 urllib2 HTTPError HTTP Error 500 Internal Server Error 到目前为止 这是我的代码 我也在代理后面工作 import url
  • 如何在 FSharp 中对数组的 XML 序列化

    这就是我要找的
  • Git分支没有跟踪信息

    git pull 之后我得到这个输出 There is no tracking information for the current branch Please specify which branch you want to merge
  • 如何在 NSIS 中使用 try catch

    您好 我在安装时在 nsis 安装程序中的几台机器上遇到了奇怪的错误 使用 fontreg nsh 安装字体时给出 无效的 win32 文件句柄 我试过谷歌但没有得到这个问题的答案 现在我正在考虑抑制此消息 那么有什么方法可以抑制此消息 或
  • 数据绑定 Kendo UI 网格后保留展开的行

    这是我第一次使用 Kendo UI 我有一个带有子节点的 Kendo UI 网格 我想在数据绑定后保留扩展的行 现在 在子项中添加一行后 它会折叠起来 我尝试过来自的建议here https stackoverflow com questi
  • 是否可以为 geom_point 和 geom_segment 添加图例?

    我想知道是否可以添加图例geom point and geom segment 从 geom point 我自动获取图例 但是我不知道如何添加图例geom segment 我努力了scale linetype manual但显然它不起作用
  • MVC 是编写 ASP.NET 应用程序的最佳方式吗? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 更新 我知道没有一种最好的方法可以做所有事情 抱歉没有马上说出来 在数据访问教程的背景下 如果您必须执行他在该教程中所做的项目 如果您必须选择其
  • 如何使用MySQL全文搜索短语而不是使用LIKE

    如何使用 mysql 全文搜索来搜索短语而不是 like SELECT description FROM t WHERE info LIKE Search phrase one OR info LIKE Phrase second OR i
  • 传递 lambda 或异步 lambda 来执行?有权衡吗? [复制]

    这个问题在这里已经有答案了 我试图理解将 lambda 传递到执行 lambda 的异步方法的两种方法的后果 下面的示例总结了这两种方法 在第一种方法中 lambda 本身是异步的 而在第二种方法中则不是 虽然这是一个人为的示例 但我试图确