2012-12-30 53 views
4

我有以下情形:每次調用async void方法時是否創建一個新線程?

async void DoStuff() { 
    // ... 
} 

button1.Click += (s, p) => { 
    DoStuff(); 
}; 

我不知道當我打電話的async void方法,而第一個呼叫仍然是不完整會發生什麼。 調用會在每次調用時創建一個新線程,還是調用會銷燬並覆蓋以前創建的線程?另外,如果前面的假設是正確的,將共享局部方法變量嗎?

編輯:

我誤解了async await的事情,因爲在Windows 8的應用程序,它的行爲不同。如果您認爲調用異步方法與創建像我這樣的新線程相同,請參閱this clarifying aricle

+0

真的很不錯鏈接 –

回答

8

我不知道當我打電話異步方法無效不止一次在同一時間

如果出現另一個呼叫,而第一個呼叫仍然是不完整你的意思是(可能暫停會發生什麼」 「)?它會工作得很好。沒有「壓倒一切」,沒有「摧毀」。你最終會得到狀態機的另一個實例(這是編譯器爲你構建的)。

兩個狀態機將擁有完全獨立的局部變量等。當然,只能在一個時間其實運行,除非某處異步方法你避免捕捉上下文其中之一。

不要忘記,啓動一個異步方法不會開始一個新的線程。一些異步操作啓動異步方法可能會啓動新線程,但這是另一回事。生成的代碼中沒有任何內容會創建新的線程。

+0

我現在正在看複合視頻上的視頻,我還是不明白。我知道awaiter的東西可能會立即返回,那樣的話,就不會發生異步事件。但是如果有實際的工作需要完成,並且UI線程接收到延續,那麼默認情況下這意味着UI線程在不忙時執行延續(這樣就不會發生任何異步)? – dudeNumber4

+0

@ dudeNumber4:不,繼續只在任務完成時執行......但它在UI線程中執行。所以是的,當UI線程不忙於做其他事情時,需要做到這一點,但它不是「隨時」不忙。請注意,UI線程應該花費大部分時間不忙。 –

6

異步方法都無關線程。
相反,異步方法將在調用者的線程上執行其代碼,就像常規方法調用一樣,直到第一個await

每個await後面的代碼將在等待回調的線程上運行。
這取決於你在做什麼await ing。
通常情況下,你會是await ing Task對象,它們默認在UI線程上運行它們的回調。

+0

我的意思是,雖然第一個電話仍然不完整 –

+0

@DanielSan:那麼是什麼?異步方法仍然與線程無關。您是否問在方法中調用的特定異步_operation_是如何工作的? – SLaks

+4

如果前一部分位於UI線程上,則延續僅在UI線程上運行。如果UI線程繁忙,則直到UI線程返回到主消息泵才能執行延續。 –

相關問題