获取 HTTP 流会阻塞渲染
Getting HTTP stream is blocking rendering
我正在从 WebAPI 下载一个流,我正在尝试 运行 在读取该流时进行编码。
下面的代码在 Blazor 服务器端或控制台应用程序上运行良好。但是在 blazor-client 端,流将在执行任何代码之前首先完全下载....即使只是 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 对此进行了测试,以确认这种情况正在发生。
这是设计使然吗?
Is this by design?
我猜这是目前的设计 !
这不会仅仅因为客户端 Blazor 支持异步/等待模式而阻塞。在我看来,真正的问题在于 HttpClient.GetStreamAsync,因为 HttpClient 服务(客户端 Blazor)不是实际或真正的 HttpClient。它基于 JavaScript 获取 Api (https://github.com/aspnet/AspNetCore/blob/master/src/Components/Web.JS/src/Services/Http.ts):
responseData = await response.arrayBuffer();
But if they switch to the mono implementation
(https://github.com/aspnet/AspNetCore/issues/10489), streaming will be
support if the browser supports it:
https://github.com/mono/mono/blob/254d6d37580a70fbb4fa072b0b2b16d2984b3bb5/sdks/wasm/framework/src/WebAssembly.Net.Http/WasmHttpMessageHandler.cs#L171-L173
A call to arrayBuffer() will never return from a pure stream. A
different MessageHandler based on this example would have to be
implemented, but I'm pretty sure it's not enough to just implement a
new message handler in this case.
希望这对您有所帮助...
我正在从 WebAPI 下载一个流,我正在尝试 运行 在读取该流时进行编码。
下面的代码在 Blazor 服务器端或控制台应用程序上运行良好。但是在 blazor-client 端,流将在执行任何代码之前首先完全下载....即使只是 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 对此进行了测试,以确认这种情况正在发生。
这是设计使然吗?
Is this by design?
我猜这是目前的设计 !
这不会仅仅因为客户端 Blazor 支持异步/等待模式而阻塞。在我看来,真正的问题在于 HttpClient.GetStreamAsync,因为 HttpClient 服务(客户端 Blazor)不是实际或真正的 HttpClient。它基于 JavaScript 获取 Api (https://github.com/aspnet/AspNetCore/blob/master/src/Components/Web.JS/src/Services/Http.ts):
responseData = await response.arrayBuffer();
But if they switch to the mono implementation (https://github.com/aspnet/AspNetCore/issues/10489), streaming will be support if the browser supports it: https://github.com/mono/mono/blob/254d6d37580a70fbb4fa072b0b2b16d2984b3bb5/sdks/wasm/framework/src/WebAssembly.Net.Http/WasmHttpMessageHandler.cs#L171-L173
A call to arrayBuffer() will never return from a pure stream. A different MessageHandler based on this example would have to be implemented, but I'm pretty sure it's not enough to just implement a new message handler in this case.
希望这对您有所帮助...