2015-03-19 54 views
2

我在理解如何使用異步和等待工作方面有點困難。異步和等待:多個等待表達式

我明白,當異步方法命中await表達式時,該方法會立即返回,並且在將來的某個時刻await表達式會返回並繼續執行該方法。

那麼我不明白,當一個異步方法包含多個await表達式時會發生什麼?當執行命中第二個await表達式時,由於該方法在第一個await表達式命中後已經返回,圍繞第二個await表達式執行會發生什麼?

我目前正在閱讀關於異步和等待的兩本書,但是我的黑暗頭腦已經被照亮了!

回答

5

我明白,當異步方法命中await表達式時,該方法會立即返回,並且在將來某個時刻await表達式返回並繼續執行該方法。

是的,如果等待尚未完成。

當執行命中第二個await表達式時,由於該方法在第一個await表達式被命中後已經返回,第二個await表達式的執行會發生什麼?

它將控制權返回給繼續執行的任何內容,這將取決於上下文。在UI線程的WinForms應用程序中,它只是事件循環。在線程池線程中,它只是線程池調度程序。

機會就在於繼續根本不關心它的任何調用 - 它只是「在某種情況下執行的東西」。它很可能會繼續,只需執行下一步需要做的任何事情(或者等到有更多的工作)。

最重要的一點是,現在的第一調用者有適當TaskTask<T>,這樣當整個異步方法已經完成,他們可以告訴。

+0

不是很簡單的答案:與第一個等待相同。即該方法也會立即在第二點返回,除非已經完成,並且在將來第二個等待表達式返回並且該方法繼續再次執行。這發生在方法中可能順序發生的所有等待中。 – 2015-03-19 12:05:34

+0

@PhilipStuyck:問題在於OP對於第二個調用方*返回的方法感到困惑(我相信)。 – 2015-03-19 12:06:20

+0

因此,當第一個awaitable正在執行時,代碼返回以完成調用者的代碼?而在第二個等待期間,控制權返回到UI線程或線程池調度程序? – serlingpa 2015-03-19 12:43:26

1

它可能有助於回想一下,每等待編譯器遇到它,它將重寫該方法的其餘部分作爲延續。所以2個等待着將導致2(嵌套的)延續,大致相當於(雖然過於簡化的),用於:

FirstAsyncThing().ContinueWith(x => { 
    SecondAsyncThing().ContinueWith(y => { 
     // etc. 
    }); 
}); 

因此,正如第一AWAIT立即返回控制給方法的調用者,所述第二控制返回到第一延續的調用者,這是原始方法的第一部分。