[英]How are async void event handlers called in C#?
如果我將我的事件處理程序聲明為async void
,它們是由.NET框架同步還是異步調用的?
即,給出以下代碼:
async void myButton_click(object sender, EventArgs e) {
do stuff
await longRunning()
do more stuff
}
我可以確定在GUI線程上執行“do stuff”行嗎?
事件處理程序將被同步調用,並且不等待(等待)直到事件處理程序完成,但等待直到事件處理程序返回。
如果以前的句子足夠混亂,我會盡力解釋清楚。 當執行所有等待點並且已到達方法體的末尾或執行任何return語句時,異步方法完成(忽略異常)。 但是,只要您點擊尚未完成的Task
的第一個await語句,異步方法就會返回。 換句話說,異步方法可以返回幾次,但只能完成一次。
所以現在我們知道異步方法何時完成並返回。 事件處理程序將假定您的方法一旦返回就完成,而不是實際完成時。
一旦事件處理程序到達第一個await
語句,它就會返回,如果有更多方法附加到同一個事件處理程序,它將繼續執行它們而不等待異步方法完成。
是的, do stuff
會在UI線程,如果UI線程觸發事件,是的執行do more stuff
也將在UI線程只要執行為longRunning().ConfigureAwait(false)
不叫。
它們將被調用,就像調用任何其他非async-await
方法一樣:
Click(this, EventArgs.Empty);
因為這個特定的事件處理程序是一個async
方法,所以調用將同步運行,直到達到await
,其余的將是一個延續。 這意味着在GUI線程上同步執行do stuff
。 然后調用者繼續前進,而不知道async
操作尚未完成。
還會在GUI線程上執行do more stuff
,但原因不同。 GUI環境中的SynchronizationContext
確保將延續發布到單個GUI線程,除非您明確告訴它不要使用await longRunning().ConfigureAwait(false)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.