gpt4 book ai didi

c# - await 不会按预期使用 StreamReader.ReadToEndAsync() 返回给调用者

转载 作者:太空宇宙 更新时间:2023-11-03 18:23:01 25 4
gpt4 key购买 nike

尝试理解流和async/await。如果我正确理解 await 将执行返回给调用者,那么我预计下面代码的结果是:

before calling async ReadToEnd
after the call to ReadToEnd
before calling async ReadToEnd
after the call to ReadToEnd

但它确实是

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.ReadToEndAsync() 时,使用带有 FileStreamStreamReader 确实返回给调用者,但它确实将 StreamReader 与下面的 MemoryStream 一起使用时不起作用。

为了了解发生了什么,我阅读了 .NET 源代码并得出结论,最终使用 MemoryStream 调用 StreamReader.ReadToEndAsync()在 BaseStream 上调用 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());
}
}

最佳答案

await 只有在等待的事情没有同步完成时才将执行返回给调用者。是的,async 方法可以选择同步完成,因为:

  • 他们已经知道答案(缓存结果、缓冲数据、已知故障状态等)
  • 他们没有合适的异步下游操作来执行根本

MemoryStream总是同步的,所以它总是这样做。

FileStream,相比之下,可能会也可能不会同步完成,这取决于缓冲区中可用的数据等。

关于是否返回调用者的决定由 GetAwaiter().IsCompleted 驱动,它(对于 Task)归结为 .IsCompleted

关于c# - await 不会按预期使用 StreamReader.ReadToEndAsync() 返回给调用者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44517607/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com