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

C# ASP.NET MVC异步调用OpenAI及视图更新问题咨询

问题解答

一、现有代码是否实现了异步并行?

你的代码是异步但串行的,并没有实现并行调用。

原因:在foreach循环中,每次调用CompleteChatAsync获取任务后立刻await chatResult,这会导致当前线程等待该任务完成后,才会进入下一次循环发起下一个请求。所有OpenAI请求是依次执行的,并没有同时发起。

正确的并行异步实现方式

先收集所有异步任务,再一次性等待全部完成,示例代码如下:

// 1. 收集所有异步任务
var tasks = new List<Task<ClientResult<ChatCompletion>>>();
foreach (ChatMessage msg in messages)
{
    List<ChatMessage> tmpMessage = new List<ChatMessage> { msg };
    tasks.Add(client.CompleteChatAsync(tmpMessage, chatOptions));
}

// 2. 等待所有任务并行完成
await Task.WhenAll(tasks);

// 3. 处理所有结果
foreach (var task in tasks)
{
    if (task.IsCompletedSuccessfully && task.Result.Value != null)
    {
        output.Add(task.Result.Value.Content[0].Text);
    }
}

注意:IsCompletedSuccessfully比IsCompleted更严谨,能排除任务失败或取消的情况。

二、ASP.NET MVC中如何解决视图不更新、一直等待的问题?

ASP.NET MVC默认是服务器端渲染模式,必须等Action中的所有逻辑完成后,才会生成完整视图返回给浏览器,所以会出现一直等待的情况。要实现实时刷新视图,需要结合前端异步或实时通信技术,以下是几种可行方案:

方案1:前端AJAX异步请求(最简单)

  • 后端:编写一个ApiController,提供单个处理OpenAI请求的接口:
public class OpenAIController : ApiController
{
    public async Task<IHttpActionResult> ProcessMessage([FromBody] ChatMessage msg)
    {
        var tmpMessage = new List<ChatMessage> { msg };
        var result = await client.CompleteChatAsync(tmpMessage, chatOptions);
        if (result.Value != null)
        {
            return Ok(result.Value.Content[0].Text);
        }
        return BadRequest("请求失败");
    }
}
  • 前端:在页面中用JavaScript循环发起AJAX请求,每个请求完成后立即更新页面内容:
// 假设messages是前端的消息数组
const messages = [/* 你的消息数据 */];
const resultContainer = document.getElementById('result-container');

messages.forEach(async (msg) => {
    const response = await fetch('/api/OpenAI/ProcessMessage', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(msg)
    });
    const text = await response.text();
    const div = document.createElement('div');
    div.textContent = text;
    resultContainer.appendChild(div);
});

方案2:Server-Sent Events (SSE) 服务器推送

适合单向实时推送场景,服务器完成一个任务就向前端推送一次结果:

  • 后端:编写一个返回EventStream的Action:
public async Task ProcessMessages(List<ChatMessage> messages)
{
    Response.ContentType = "text/event-stream";
    Response.BufferOutput = false;

    foreach (ChatMessage msg in messages)
    {
        var tmpMessage = new List<ChatMessage> { msg };
        var result = await client.CompleteChatAsync(tmpMessage, chatOptions);
        if (result.Value != null)
        {
            await Response.WriteAsync($"data: {JsonConvert.SerializeObject(result.Value.Content[0].Text)}\n\n");
            await Response.FlushAsync();
        }
    }
}
  • 前端:监听SSE事件,实时更新页面:
const eventSource = new EventSource('/Home/ProcessMessages');
const resultContainer = document.getElementById('result-container');

eventSource.onmessage = function(event) {
    const text = event.data;
    const div = document.createElement('div');
    div.textContent = text;
    resultContainer.appendChild(div);
};

eventSource.onerror = function() {
    eventSource.close();
};

方案3:SignalR双向通信

适合更复杂的实时交互场景,支持服务器和客户端双向通信:

  1. 安装SignalR NuGet包:Install-Package Microsoft.AspNet.SignalR
  2. 创建Hub类:
public class OpenAIHub : Hub
{
    public async Task ProcessMessages(List<ChatMessage> messages)
    {
        foreach (ChatMessage msg in messages)
        {
            var tmpMessage = new List<ChatMessage> { msg };
            var result = await client.CompleteChatAsync(tmpMessage, chatOptions);
            if (result.Value != null)
            {
                await Clients.Caller.SendAsync("ReceiveResult", result.Value.Content[0].Text);
            }
        }
    }
}
  1. 前端连接Hub并接收结果:
const connection = $.hubConnection();
const openAIHub = connection.createHubProxy('openAIHub');

openAIHub.on('ReceiveResult', function(text) {
    const div = document.createElement('div');
    div.textContent = text;
    document.getElementById('result-container').appendChild(div);
});

connection.start().done(function() {
    // 发送消息列表到服务器
    openAIHub.invoke('ProcessMessages', [/* 消息数组 */]);
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 15:13:16