2016-11-04 67 views
-1

考虑下面的代码:为什么要等待退出?

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中,工作完成。

+1

当'async'方法找到'await'时,它会将方法执行委托给另一个线程,并且方法立即返回。当方法执行完成时,它会回滚执行该方法的其余部分。 –

+0

@NiyokoYuliawan在我的情况下,我希望webjob继续运行(不报告“已完成”),直到所有工作完成。我看到的行为是'DoOtherStuff'永远不会被记录到webjob,除非我使用'Wait' – SB2055

+0

如果您使用的是webjobs,您的问题是http://stackoverflow.com/questions/22916325/azure- webjobs-can-i-use-async-methods请包含调用'HandleMessage'的代码,这可能是您的问题所在。 –

回答

3

除非您正在编写事件处理函数,否则绝不应该这样做async void。 A Actionasync修饰符是async void方法。你需要做的说法一Func<Task>,然后做await action()RunRecurringTask

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处理函数。