嘗試瞭解流和async/await
。如果我undertand正確await
返回執行調用者,所以我希望下面的代碼的結果是:await不會按預期的方式返回給調用方使用StreamReader.ReadToEndAsync()
before calling async ReadToEnd
after the call to ReadToEnd
before calling async ReadToEnd
after the call to ReadToEnd
但insted的是
before calling async ReadToEnd
after the call to ReadToEnd
before calling async ReadToEnd
after await in ReadToEnd. streamReader.BaseStream.GetType(): System.IO.MemoryStream
after the call to ReadToEnd
看來,使用StreamReader
與FileStream
下撥打StreamReader.ReadToEndAsync()
時確實返回給主叫方,但在使用底下的MemoryStream
時使用StreamReader
時不起作用。
試圖瞭解是怎麼回事,我就BaseStream閱讀.NET源代碼,並來到conculssion,調用StreamReader.ReadToEndAsync()
與MemoryStream
下最終調用ReadAsync()
(source)。在MemoryStream
的情況下ReadAsync()
只是不是一個真正的異步方法,因此不會返回給調用者。
我的理解是否正確?
using System;
using System.Text;
using System.Linq;
using System.IO;
using System.Threading.Tasks;
static class Program
{
public static void Main(string[] args)
{
var longString = new string(Enumerable.Repeat('x', 100000000).ToArray());
File.WriteAllText("bigFile.txt", longString, Encoding.UTF32);
StreamReader fileStreamReader = new StreamReader(File.OpenRead(@"bigFile.txt"));
Console.WriteLine("before calling async ReadToEnd");
var task = ReadToEnd(fileStreamReader);
Console.WriteLine("after the call to ReadToEnd");
byte[] bytes = Encoding.UTF32.GetBytes(longString);
StreamReader memoryStreamReader = new StreamReader(new MemoryStream(bytes));
Console.WriteLine("before calling async ReadToEnd");
var task2 = ReadToEnd(memoryStreamReader);
Console.WriteLine("after the call to ReadToEnd");
fileStreamReader.Dispose();
memoryStreamReader.Dispose();
}
static async Task ReadToEnd(StreamReader streamReader)
{
string allText = await streamReader.ReadToEndAsync();
Console.WriteLine("after await in ReadToEnd. streamReader.BaseStream.GetType(): " + streamReader.BaseStream.GetType());
}
}
我認爲這樣做,但MemoryStream足夠快,立即返回。因此,您會看到額外的Console.WriteLine出現在您期望的之前。在await和Console之間添加一個Sleep。WriteLine,看看會發生什麼...... – AroglDarthu
@AroglDarthu它實際上並不是一個「足夠快」的問題 - 它只是*不是異步*;一種方法可以是以下任何一種:慢速和同步,慢速和異步,快速和同步,快速和異步。 Fast vs Slow是沒有實際意義的 - 它只是同步vs異步纔有意義(在合理的範圍內;顯然,如果它是異步的並且足夠快以至於能夠擊敗ret指令,那麼......好吧,也許;但是這是一個邊緣案例這沒關係) –
@MarcGravell感謝您的洞察力。 – AroglDarthu