1

我知道有這個代碼之間的差異:爲什麼我應該更喜歡使用API​​異步函數來包裝與Task.Run同步的函數呢?

var streamWriter = new StreamWriter("something.txt"); 
streamWriter.WriteAsync("text"); 

這:

var streamWriter = new StreamWriter("something.txt"); 
Task.Run(()=> streamWriter.Write("text")); 

第一個更有道理。

,並在不同的情景,當我在等待一個結果,此代碼:

var streamReader = new StreamReader("something.txt") 
char[] chars = new char[10]; 

Task<int> task = streamReader.ReadAsync(chars, 0, chars.Length); 
//Do something... 

int num = await task; 
//Do something with num... 

更有道理比這

var streamReader = new StreamReader("something.txt") 
char[] chars = new char[10]; 

Task<int> task = Task.Run(()=>streamReader.Read(chars, 0, chars.Length)); 
//Do something... 

int num = await task; 
//Do something with num... 

我想利用內置的異步API是不僅更清晰,而且它實際上比ThreadPool線程無故等待更好,更有效地管理ThreadPool線程。

是不是?

+0

這是典型的純異步vs異步同步問題。 –

+0

下注是實施了'DoSomethingSomethingAsync'方法的人瞭解問題域,並且實現了一個很好的異步執行故事。另一方面,產生一個明確的任務來做同步調用幾乎是說:「我不相信他們」。我認爲你應該相信他們。 –

+0

一般來說,假設你有選擇,它*應該總是比使用異步方法更好地產生一個任務,然後在該任務中調用一個同步方法。再次,假設做出異步方法的人知道他們在做什麼。 –

回答

4

包裝在Task.Run中的同步調用將在該操作期間阻塞線程池線程。一個真正異步的實現will not

特別是對於流,操作是否「真正異步」可能有點難以確定。例如,網絡流總是真正異步的,內存流永遠不會是真正的異步,並且如果您將特殊標誌傳遞給它們的構造函數,則文件流只是真正的異步。