【问题标题】:Why is await exiting?为什么等待退出?
【发布时间】:2016-11-04 03:36:04
【问题描述】:

给定以下代码:

    public async Task Send() // part of Sender class
    {
          // sync code
    }

    // // 

    private async Task HandleMessage()
    {
        // await sender.Send(); // exits HandleMessage immediately
        sender.Send().Wait(); // works as expected, waiting to complete
        DoOtherStuff(); // doesn't get hit with await
        return;
    }

    RunRecurringTask(async () => await HandleMessage(), result);

    public void RunRecurringTask(Action action, RecurringTaskRunResult result)
    {
            action();
            result.DoStuff();
    }

我认为await 告诉线程在等待的事情完成后返回,但由于某种原因,这似乎没有发生:剩余的代码永远不会被命中,一切都只是......停止。这可能是什么原因造成的?

这是一个 Azure WebJob 中的控制台应用程序,物有所值。当使用Wait 时,我得到了预期的结果,但是使用await,工作就完成了。

【问题讨论】:

  • async方法找到await时,它会将方法执行委托给另一个线程,方法立即返回。当方法执行完成后,它将返回执行方法的其余部分。
  • @NiyokoYuliawan 就我而言,我希望网络作业继续运行(而不是报告“已完成”),直到所有工作完成。我看到的行为是 DoOtherStuff 永远不会登录到网络作业,除非我使用 Wait
  • 如果您使用 webjobs,您的问题与 stackoverflow.com/questions/22916325/… 重复请包括调用 HandleMessage 的代码,这可能是您的问题所在。
  • @ScottChamberlain 更新

标签: c# .net async-await


【解决方案1】:

除非您正在编写事件处理程序,否则您永远不应该使用async void。带有async 修饰符的Actionasync void 方法。您需要将参数设为Func<Task>,然后在您的RunRecurringTask 中执行await action()

private async Task HandleMessage()
{
    await sender.Send();
    DoOtherStuff();
    return;
}

RunRecurringTask(async () => await HandleMessage(), result);
//You also could do 
//RunRecurringTask(() => HandleMessage(), result);

public async Task RunRecurringTask(Func<Task> action, RecurringTaskRunResult result)
{
        await action();
        result.DoStuff();
}

如果您有其他未标记为async 的方法,则需要将它们全部更改为调用堆栈,直到您从 SDK 到达入口点。 SDK 了解如何处理具有async Task 返回类型since the 0.4.0-beta version 的函数。

【讨论】:

    猜你喜欢
    • 2015-02-24
    • 2021-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-12
    相关资源
    最近更新 更多