1

我正在从 WebAPI 下载流,并尝试在读取流时运行代码。

下面的代码在 Blazor 服务器端或控制台应用程序上运行良好。但是在 blazor 客户端,流将首先完全下载,然后再执行任何代码......即使只是一个 Console.WriteLine() 也会在流完成后开始写入控制台。我正在使用最新的 .Net Core 3.0 Preview 8 ...

public async IAsyncEnumerable<SomeClass> GetDataAsync()
{
    var serializer = new JsonSerializer();
    using (var stream = await Http.GetStreamAsync("https://localhost:44334/api/values/i"))
    {
        using (var sr = new StreamReader(stream))
        using (var jr = new JsonTextReader(sr))
        {
            while (await jr.ReadAsync()) //<-- Stream is fully download to browser before taking any actions.
            {
                if (jr.TokenType != JsonToken.StartArray && jr.TokenType != JsonToken.EndArray)
                {
                    Console.WriteLine(jsonReader.LinePosition);
                    yield return serializer.Deserialize<SomeClass>(jr);
                }
            };
        }
    }
}

我用 WireShark 对此进行了测试,以确认这种情况正在发生。

这是设计使然吗?

4

1 回答 1

0

这是设计使然吗?

我想它目前是设计使然

这不会仅仅因为客户端 Blazor 支持异步/等待模式而阻塞。在我看来,真正的问题在于 HttpClient.GetStreamAsync,因为 HttpClient 服务(客户端 Blazor)不是实际的或真正的 HttpClient。它基于 JavaScript Fetch Api(https://github.com/aspnet/AspNetCore/blob/master/src/Components/Web.JS/src/Services/Http.ts):

responseData = await response.arrayBuffer(); 

但是如果他们切换到单声道实现(https://github.com/aspnet/AspNetCore/issues/10489),如果浏览器支持,则支持流式传输: https ://github.com/mono/mono/blob/ 254d6d37580a70fbb4fa072b0b2b16d2984b3bb5/sdks/wasm/framework/src/WebAssembly.Net.Http/WasmHttpMessageHandler.cs#L171-L173

对 arrayBuffer() 的调用永远不会从纯流返回。必须实现基于此示例的不同 MessageHandler ,但我很确定在这种情况下仅实现新的消息处理程序是不够的。

希望这可以帮助...

于 2019-08-21T17:06:45.133 回答