【问题标题】:Async processing from scratch从头开始异步处理
【发布时间】:2015-01-09 04:09:17
【问题描述】:

我有以下名为 Pluck 的课程:

internal static void Work()
{
    Task[] tasks = new Task[5];
    for (int i = 0; i < tasks.Length; i++)
    {
        tasks[i] = SumAsync();
    }
    Task.WhenAll(tasks);
}

private static async Task<int> SumAsync()
{
    return await Task.Run(() => { return OnePlusOne(); });
}

private static int OnePlusOne()
{  return 1+1;  }

还有我的主要方法:

static void Main(string[] args)
{
    Pluck.Work(); 
}

我遗漏了一些东西,因为我在 OnePlusOne 中切换了一个断点并且永远不会被命中。

【问题讨论】:

  • Task.WhenAll 不是阻塞方法。它返回一个您可以等待的任务。请改用Task.WaitAll
  • SumAsync 中使用async/await 也没有任何意义。只需返回Task.Run创建的任务即可。
  • 你一定有其他问题。 1+1 上的断点在我的机器上停止。我确实重新格式化了代码,在不同的行上有花括号(如上帝所愿)。
  • @SteveWellens 这是一个竞争条件,因为应用程序可以在这些任务安排之前结束。
  • @SteveWellens:任务在后台线程上运行,不会阻止进程退出。操作系统肯定停止这些线程而不会引发错误;如果进程中的所有前台线程都退出,它们会在没有仪式的情况下简单地终止。这正是这里发生的事情。

标签: c# .net multithreading async-await


【解决方案1】:

Task.WhenAll(tasks) 是一个async 方法,因此返回一个Task。您需要await 该任务以确保仅在完成所有任务后继续。目前,您的应用程序可能会在这些任务有机会运行之前结束。

这导致使用 async 关键字标记 Work 并让它返回 Task 本身:

internal static async Task WorkAsync()
{
    Task[] tasks = new Task[5];
    for (int i = 0; i < tasks.Length; i++)
    {
        tasks[i] = SumAsync();
    }
    await Task.WhenAll(tasks);
}

由于不能在Main中使用await,所以需要与Wait同步等待:

static void Main(string[] args)
{
    Pluck.WorkAsync().Wait(); 
}

如果单个await 是您在方法中执行的最后一件事(如在您的SumAsync 和我的WorkAsync 中),您可以删除它和async 关键字并简单地返回任务。这略微提高了性能。更多相关信息here


注意:您应该只在非常特殊的情况下(例如在Main 内部)阻止带有Wait 的任务,因为它可能导致死锁。更好的解决方案是使用AsyncContext

【讨论】:

  • FWIW:WorkAsync() 方法也不需要是 async。它也可以只返回WhenAll()方法的返回值。
  • @PeterDuniho 当然。但这是一个过早的优化,附加值微不足道。
  • 嗯?它完全与您的评论“过早的优化”相同,即“制作SumAsyncasync”是没有用的。这是否意味着您不将SumAsync() 设为async 方法的建议也具有“微不足道的附加值”?如果是这样,你为什么要提这个?
  • 大声笑...真的吗?当您指出该方法不需要是async 时,我认为您的答案好多。我实际上不同意这是一种“过早的优化”,因为它是一种“不要编写毫无意义的代码”。哦,好吧……适合自己。
  • 同意彼得的观点,并不是说代码会变慢(在大多数情况下确实如此,但还不够重要),而不仅仅是给代码增加了不必要的复杂性。不添加多余的代码,特别是像async 那样复杂的代码,才是价值的来源。当真正需要这种复杂性来完成某件事时,就是值得使用的时候。
猜你喜欢
  • 2023-02-05
  • 2022-11-11
  • 2018-12-01
  • 2015-08-10
  • 2019-08-29
  • 1970-01-01
  • 2013-04-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多