Получение HTTP-потока блокирует рендеринг

Я загружаю поток из 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, чтобы подтвердить, что это происходит.

Это по замыслу?

1 ответ

Решение

Это по замыслу?

Я предполагаю, что это в настоящее время разработано!

это не будет блокировать просто потому, что шаблон асинхронного / ожидающего поддерживается в 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(); 

Но если они переключатся на реализацию mono ( 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, основанный на этом примере, но я уверен, что в этом случае недостаточно просто реализовать новый обработчик сообщений.

Надеюсь это поможет...

Другие вопросы по тегам