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

特别是对于流,操作是否“真正异步”可能有点难以确定。例如,网络流总是真正异步的,内存流永远不会是真正的异步,并且如果您将特殊标志传递给它们的构造函数,则文件流只是真正的异步。