.NET Core 3.1如何用异步任务实现页面无刷新分步更新?
实现分步异步任务进度展示的最简方案
后端(GetFiles.cshtml.cs)
- 添加处理任务启动的异步方法,通过Server-Sent Events(SSE)推送进度:
public async Task<IActionResult> OnPostStartTasksAsync() { // 配置SSE响应头 Response.ContentType = "text/event-stream"; Response.Headers["Cache-Control"] = "no-cache"; Response.Headers["Connection"] = "keep-alive"; // 推送初始启动消息 await SendProgressMessage("Task started..."); // 执行数据库查询任务 await SendProgressMessage("Query started"); // 模拟数据库查询耗时,替换为实际业务逻辑 await Task.Delay(2000); await SendProgressMessage("Query ended"); // 执行文件创建任务 await SendProgressMessage("Create file started"); // 模拟文件创建耗时,替换为实际业务逻辑 await Task.Delay(3000); await SendProgressMessage("File creation finished"); // 推送任务完成标记 await SendProgressMessage("done"); return new EmptyResult(); } // 封装SSE消息发送逻辑 private async Task SendProgressMessage(string message) { var sseFormatMessage = $"data: {message}\n\n"; await Response.WriteAsync(sseFormatMessage); await Response.Body.FlushAsync(); }
前端(GetFiles.cshtml)
- 添加按钮和进度展示容器:
<button id="startTasksBtn">Get Files</button> <div id="progressContainer"></div>
- 编写JavaScript处理点击事件与进度接收:
document.getElementById('startTasksBtn').addEventListener('click', function() { const btn = this; const progressBox = document.getElementById('progressContainer'); // 禁用按钮并添加初始提示 btn.disabled = true; addProgressText("Task started..."); // 建立SSE连接 const eventSource = new EventSource('/GetFiles?handler=StartTasks'); eventSource.onmessage = function(event) { const msg = event.data; if (msg === 'done') { // 任务结束,关闭连接并恢复按钮状态 eventSource.close(); btn.disabled = false; return; } // 追加进度文本 addProgressText(msg); }; // 处理连接异常 eventSource.onerror = function() { addProgressText("任务执行出错"); eventSource.close(); btn.disabled = false; }; }); // 封装进度文本追加逻辑 function addProgressText(text) { const p = document.createElement('p'); p.textContent = text; document.getElementById('progressContainer').appendChild(p); }
核心说明
- 采用SSE是当前场景下的最简方案,无需引入SignalR等额外依赖,原生支持单向进度推送。
- 后端顺序执行任务,每完成一个阶段就推送进度消息,前端实时接收并更新页面,完全避免整页刷新。
- 代码逻辑清晰,替换模拟耗时的
Task.Delay为实际业务代码即可直接复用。
内容的提问来源于stack exchange,提问作者cdub
相关产品推荐
相关产品推荐

