为什么不等待我传递给 Task.Run() 的异步操作?

2023-12-12

我在这里有一种非常奇怪的感觉,我错过了一些东西,但现在我已经在这个问题上苦苦挣扎了几个小时,但无法得到它。我有一种任务调度类,它主要接收它启动的正常同步操作,而不是通过 Task.Run() 异步操作。但是,当它收到传递的异步操作时,它会返回而不等待等待任务。我将其简化为以下示例:

private async void Button_OnClick(object sender, RoutedEventArgs e)
{
    Logger("Click event received");
    await OperationProcessor(async () =>
    {
        Logger(">>> Starting ACTION, waiting 5 seconds");
        await Task.Delay(5000);
        Logger(">>> ACTION finished");
    });
    Logger("Click event finished");
}

private static async Task OperationProcessor(Action operation)
{
    Logger("Processing started, waiting a second");
    await Task.Delay(1000);
    Logger("Launching action");
    await Task.Run(operation);
    Logger("Returned from action, waiting another second");
    await Task.Delay(1000);
    Logger("Processing finished");
}

private static void Logger(string message)
{
    Console.WriteLine($"{DateTime.Now:dd.MM.yy HH:mm:ss} [{Thread.CurrentThread.ManagedThreadId}] {message}");
}

这会产生以下输出:

1: 16.07.19 10:58:06 [1] Click event received
2: 16.07.19 10:58:06 [1] Processing started, waiting a second
3: 16.07.19 10:58:07 [1] Launching action
4: 16.07.19 10:58:07 [7] >>> Starting ACTION, waiting 5 seconds
5: 16.07.19 10:58:07 [1] Returned from action, waiting another second
6: 16.07.19 10:58:08 [1] Processing finished
7: 16.07.19 10:58:08 [1] Click event finished
8: 16.07.19 10:58:12 [7] >>> ACTION finished

如何让 5 等待 4 开始的操作?


为什么不等待我传递给 Task.Run() 的异步操作?

因为这是不可能的await a void.

常见的是talk关于“等待方法”或“等待委托”,但这可能会产生误导。实际发生的情况是,首先调用该方法,然后调用其他方法returns正在等待。并且不可能等待结果Action因为该代表返回void.

这是最好的主要原因avoid async void。在这种情况下,async void很狡猾,因为它是一个 lambda 表达式。

异步相当于void Method() is async Task MethodAsync(), 所以异步委托相当于Action is Func<Task>。这就是为什么添加Func<Task>超载起作用了。您可以同时保留Action and Func<Task>重载,编译器会智能地选择Func<Task>过载async拉姆达。

我有一种任务调度类

If your Func<Task>解决方案足够好,然后保持原样。但如果你想更深入一点的话,那就是possible检测(并等待)async void方法。async void方法与当前交互SynchronizationContext。既然你有自己的“调度类”,你might想要考虑提供SynchronizationContext对于该类安排的代码。如果您有兴趣,可以向我借用AsyncContext class它本质上只是一个单线程工作队列SynchronizationContext.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么不等待我传递给 Task.Run() 的异步操作? 的相关文章

随机推荐

  • 在模态中将 Jquery 变量传递给 php

    我正在打印图片和姓名 在网格视图中 用户将能够单击图片或名称 这将打开一个模式 其中包含所单击的图片 名称的标题 将相同
  • javascript/jQuery setInterval/clearInterval

    我正在使用 setInterval 来检查 p html 段落 是否具有特定的文本值 如果有的话我想清除间隔并继续代码流 我在 jQuery 插件中使用它 所以如果段落有 tat 文本值 我想清除间隔 然后继续使用回调函数 所以我尝试了这样
  • 如何在 DB2 中查找表的主键的名称和值

    如何找到表的主键列名和值 我尝试在 SYSCAT 表中查找 但找不到任何相关内容 这应该为您提供大型机上所需的内容 http publibz boulder ibm com cgi bin bookmgr OS390 BOOKS DSNSQ
  • 扩展 woocommerce Rest api

    我想扩展 woocommerce Rest api 以包含其 预订 扩展插件的数据 目前此扩展没有其余 api 提供的默认端点 到目前为止 我已经创建了一个插件 并添加了以下代码 add filter woocommerce rest pr
  • 获取 Recycler View 上单击的项目的位置

    我已经实施了RecyclerView而且效果很好 我有一个ArrayList其中包含回收器视图的数据 每个项目的布局都很复杂 它包含两个frameLayout Framelayout1 包含一个图像和一个文本 framelayout2 包含
  • 不允许使用 HTTP 动词 POST 来访问路径“/”

    整个错误 Server Error in Application The HTTP verb POST used to access path is not allowed Description An unhandled exceptio
  • 多处理时在哪里调用 join()

    在 Python 中使用多处理时 我通常会看到以下示例 join 函数在每个进程实际创建的单独循环中调用 例如 这个 processes for i in range 10 p Process target my func processe
  • 如何找到数组中的第一个空闲键

    我们都知道 数组实际上是 PHP 中的有序树 鉴于此 数组索引 整数键 不需要遵循任何严格的顺序 甚至根本不需要存在 所以 给定一个像这样的数组 array 1 gt A 5 gt B 2 gt C 3 gt D 6 gt E 0 gt F
  • 一旦超出索引,C# 将数组索引值循环回数组开头

    我希望创建一个如下所示的程序 c 顺便说一句 int arr new int 9 some code that puts values 1 0 or 2 in each array element for int i 0 i lt arr
  • 如何在 bash 中使用 getopts 的示例

    我想打电话myscript文件以这种方式 myscript s 45 p any string or myscript h should display help myscript should display help 我的要求是 get
  • 如何在 Ubuntu 操作系统上使用 cron 作业每天运行 php 脚本

    运行命令我正在使用 ubuntu 12 和 lamp 服务器 我想每 1 小时运行一次 php 脚本 我已经创建了一个 crontab 来执行此操作 如果我使用命令 crontab l 检查我的 cron 列表 它会显示如下 Edit th
  • 如何在 R 中将数据帧上传到 ndtv?

    我的目标是使用 R 中的三个包进行动态可视化 ndtv network and networkDynamic包 我创建了一个dataset根据此示例数据集排序的信息网络动态时间可视化研讨会 第 7 页 根据网络动态手册第49页 上传数据集并
  • 在模式弹出窗口中打开外部网站

    我知道 a href http www example com target blank Click here a 打开链接在新标签中 Chrome 和 Firefox 中的默认行为 a href http www example com
  • 通过 jQuery GET 强制“另存为”对话框

    我在下面的 test php 文件代码中调用 jQuery GET 我试图让脚本在生成的 test ini 文件上弹出 另存为 对话框 以允许将其保存在本地 然而 虽然我可以将结果回显给 jQuery 但我似乎无法弹出 另存为 对话框 更新
  • 如何将一系列单元格存储到数组中?

    如果我在单元格 A1 A150 中有一个数据列表 但数量可能会有所不同 有没有办法将其推入数组 而无需单独查看每个单元格来确定它是否为空 这样做超出了我的执行时间 我需要一种更快的方法来存储数据并在数据到达空单元格时停止 以下是我目前的做法
  • 当didUpdateToLocation发生时,iphone在后台发送邮件

    我开始工作 skpsmtpmessage http code google com p skpsmtpmessage 这样我就可以在前台发送邮件 现在我希望在 didUpdateLocation 发生时通过 skpsmtpmessage 在
  • 特定时间段内的多笔交易,受日期范围限制

    我有一个包含交易 人员 交易日期 物品等的数据库 每次有人购买商品时 交易都会存储在表中 如下所示 personNumber TransactionNumber TransactionDate ItemNumber 我想要做的是找到从 20
  • Java观察者更新函数

    我有一个实现观察者的类 当然它需要有更新功能 public void update Observable obs Object obj 谁能解释一下这两个参数代表什么 Observable 当然是我的 observable 但是 我如何通过
  • bash 中的 printf:“09”和“08”是无效数字,“07”和“06”可以

    这是我的 bash 脚本 我只想用零填充一组数字 printf 04d 09 printf 04d 08 printf 04d 07 printf 04d 06 Output rename sh line 3 printf 09 inval
  • 为什么不等待我传递给 Task.Run() 的异步操作?

    我在这里有一种非常奇怪的感觉 我错过了一些东西 但现在我已经在这个问题上苦苦挣扎了几个小时 但无法得到它 我有一种任务调度类 它主要接收它启动的正常同步操作 而不是通过 Task Run 异步操作 但是 当它收到传递的异步操作时 它会返回而