RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1526740
Accepted
Xzizz
Xzizz
Asked:2023-06-21 06:38:27 +0000 UTC2023-06-21 06:38:27 +0000 UTC 2023-06-21 06:38:27 +0000 UTC

Task.Factory.StartNew - 等待并返回结果

  • 772

如何启动一堆后台线程并等待第一个线程返回结果?

在 Google 之后,我尝试了这个方法以及其他十几种方法,包括不使用 lambda。

Task task = Task.Factory.StartNew(async () =>
{
    AnalyseInfo analyseInfo = await myAnalyzer.AnalyseAsync();
    _analyseInfos.Add(analyseInfo);
});


Task<AnalyseInfo> task = Task<AnalyseInfo>.Factory.StartNew(async () =>
{
    return await myAnalyzer.AnalyseAsync();
});


Task<Task<AnalyseInfo>> task = Task<Task<AnalyseInfo>>.Factory.StartNew(async () =>
{
    return await myAnalyzer.AnalyseAsync();
});

但没能得到想要的结果。

我想使用等待任何完成的任务Task.WaitAny

// Дождаться завершения любой задачи
int numTask = Task.WaitAny(_tasks.ToArray());

所有尝试都以任务在完成之前获得完成状态而结束。

c#
  • 2 2 个回答
  • 70 Views

2 个回答

  • Voted
  1. Best Answer
    Pavel Mayorov
    2023-06-21T15:48:12Z2023-06-21T15:48:12Z

    Task.Factory.StartNew创建一个包装返回值的新任务,而不管该值本身如何。

    因此,当您编写 时Task.Factory.StartNew(async …),您会得到Task<Task<…>>- 一个任务,其价值也是一个任务。

    更详细地考虑异步方法:

    async () {
        // 1
        await Bar();
        // 2
    }
    

    如果调用,它将在第一个非空闲的await运算符之后返回,即第1行和对Bar的调用将同步执行,而等待Bar和第2行将异步执行。当您将此类方法包装在任务中时,第 1 行和对 Bar 的调用将在外部任务中执行,而等待 Bar 和第 2 行将在内部任务中执行。

    这就是为什么您最终会过早完成任务:您正在等待外部任务。

    如何摆脱它?非常简单:使用 Unwrap!

    Task<AnalyseInfo> t = Task.Factory.StartNew(async () =>
    {
        return await myAnalyzer.AnalyseAsync();
    }).Unwrap();
    

    这个方法没有什么神奇之处,如果它不存在的话 - 自己编写它并不难:

    async Task<T> Unwrap<T>(Task<Task<T>> task) {
        return await await task;
    }
    

    第二个选项 - 您可以使用Task.Run,与 StartNew 不同,它对调用内部 Unwrap 的异步方法有一个特殊的重载:

    Task<AnalyseInfo> t = Task.Run(async () =>
    {
        return await myAnalyzer.AnalyseAsync();
    });
    

    最后,第三个选项是根本不将异步方法移至单独的线程,而只是调用它。此选项并不通用,但通常有效:

    Task<AnalyseInfo> t = myAnalyzer.AnalyseAsync();
    
    • 3
  2. SelfishCrawler
    2023-06-21T16:43:00Z2023-06-21T16:43:00Z

    虽然上面已经给出了答案,但我会尝试用这个例子添加我的 5 美分:

    var longTask = Task.Delay(10000);
    var shortTask = Task.Delay(1000);
    
    var tasks = new[] { longTask, shortTask };
    
    var anyTask = await Task.WhenAny(tasks);
    
    Console.WriteLine(anyTask.Status); //RanToCompeltion
    Console.WriteLine(shortTask.Status); //RanToCompletion
    Console.WriteLine(longTask.Status); //WaitingForActivation
    
    Console.WriteLine(anyTask == shortTask); //True
    

    在此示例中,TaskFactory 不用于创建,而是直接使用您的任务(这也消除了额外的异步以及为此任务创建额外的状态机)。在您的示例中,问题在实际等待的任务await之前缺少关键字。Task.WhenAny

    • 1

相关问题

  • 使用嵌套类导出 xml 文件

  • 分层数据模板 [WPF]

  • 如何在 WPF 中为 ListView 手动创建列?

  • 在 2D 空间中,Collider 2D 挂在玩家身上,它对敌人的重量相同,我需要它这样当它们碰撞时,它们不会飞向不同的方向。统一

  • 如何在 c# 中使用 python 神经网络来创建语音合成?

  • 如何知道类中的方法是否属于接口?

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5