You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET8 Blazor Hosted WASM流式响应UI实时更新异常排查

Blazor WASM流式响应未实时更新UI问题

环境背景

  • 基于.NET8的Blazor Hosted WebAssembly应用,包含Client、Server、Shared三个项目
  • Server端控制器通过IAsyncEnumerable返回后端流式数据,但客户端需等待服务器完成所有迭代后才执行JSON反序列化并更新UI

Server端控制器代码

[HttpPost, Route("/api/chat/communicate_async")]
public async IAsyncEnumerable<string> DoCommunicateAsync(ChatRequest chat)
{
    IAsyncEnumerable<string> results = _IChat.DoCommunicateAsync(chat);
    await foreach (var result in results)
    {
        yield return result;
    }
}

Client端两种流式接收尝试

方案一

CancellationToken cancellationToken = GetCancellationToken();
var requestContent = new StringContent(System.Text.Json.JsonSerializer.Serialize(chatRequest), Encoding.UTF8, "application/json");
using var requestMessage = new HttpRequestMessage(HttpMethod.Post, "api/chat/communicate_async")
{
    Content = requestContent
};
requestMessage.SetBrowserResponseStreamingEnabled(true); // 启用响应流式传输

using var response = await Http.SendAsync(requestMessage, HttpCompletionOption.ResponseHeadersRead);

using Stream stream = await response.Content.ReadAsStreamAsync(cancellationToken);
var lines = System.Text.Json.JsonSerializer.DeserializeAsyncEnumerable<string>(
    stream,
    new JsonSerializerOptions
        {
            PropertyNameCaseInsensitive = true,
            DefaultBufferSize = 128
        },
     cancellationToken);
await foreach (string? line in lines)
{
    chatResponse.response += line;
    StateHasChanged();
}

方案二

CancellationToken cancellationToken = GetCancellationToken();
chatResponse.response = string.Empty;
var requestContent = new StringContent(System.Text.Json.JsonSerializer.Serialize(chatRequest), Encoding.UTF8, "application/json");
var requestMessage = new HttpRequestMessage(HttpMethod.Post, "api/chat/communicate_async")
{
    Content = requestContent
};
//requestMessage.Headers.Accept.Append(new MediaTypeWithQualityHeaderValue("application/stream+json"));
requestMessage.SetBrowserResponseStreamingEnabled(true); // 启用响应流式传输

var response = await Http.SendAsync(requestMessage, HttpCompletionOption.ResponseHeadersRead);
IAsyncEnumerable<string?> results = response.Content.ReadFromJsonAsAsyncEnumerable<string>();
await foreach (string? result in results)
{
    chatResponse.response += result;
    StateHasChanged();
}

已查阅多篇文章并尝试调整DefaultBufferSize等方案,问题仍未解决。

2024/05/28 更新

  • 使用LLAMASharp本地大模型库的代码,虽通过IAsyncEnumerable迭代,但客户端无法实现流式传输:
await foreach (string? result in session.ChatAsync(new ChatHistory.Message(AuthorRole.User, chat.prompt), inferenceParams, cancellationToken))
{
    if (result != null)
    { yield return result; }
}
  • 使用Azure.AI库的代码可正常在客户端流式传输:
await foreach (StreamingChatCompletionsUpdate chatUpdate in client.GetChatCompletionsStreaming(completionsOptions))
{
    string? result = chatUpdate.ContentUpdate;
    if (result != null)
    { yield return result; }
}

求解决思路?

内容的提问来源于stack exchange,提问作者Stavros Koureas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 07:00:16