2016-11-04 69 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處理函數。