I'm downloading a stream from a WebAPI and I'm trying to run code while the stream is being read.
The code below works fine on Blazor server-side or an console app. But on blazor-client side the stream will first download fully before executing any code.... even just a Console.WriteLine() will just start writing to Console after the stream is done. I'm using the latest .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);
}
};
}
}
}
I tested this with WireShark to confirm that this is happening.
Is this by design?
Is this by design?
I guess it is currently by design !
this will not block simply because the async / await pattern is supported in client-side Blazor. It seems to me that the real issue is with HttpClient.GetStreamAsync, as the HttpClient service (client-side Blazor) is not the actual or real HttpClient. It is based on the JavaScript Fetch 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.
Hope this helps...