对 Controller 函数进行异步调用 (void)。无法将控制权交还给 UI

Posted

技术标签:

【中文标题】对 Controller 函数进行异步调用 (void)。无法将控制权交还给 UI【英文标题】:Making async call to Controller function (void). Not getting control back to UI 【发布时间】:2020-04-18 23:53:45 【问题描述】:

我正在开发基于 MVC 5 的报告生成 Web 应用程序(Excel 文件)。在一个“GenerateReports”页面上,单击按钮,我正在调用 StartMonthly 函数。这将控制到控制器中的 void 方法“GenerateReportMainMonthly”。此方法调用另一个 void 方法“GenerateReportMain”。在 GenerateReportMain 中,还有 5 个其他 void 函数被调用。

在报告生成完成之前,我不希望控件卡在后端。单击按钮时,警报框应显示“报告生成已开始”。并且控件应该返回到“GenerateReports”页面。

我尝试了 ajax,但无法将控件返回到 UI。如何在不等待后端进程完成的情况下将控件返回到同一页面?

$('#btnStart').on('click', StartMonthly);
function StartMonthly() 
        var url = '/GenerateReport/GenerateReportMainMonthly';
        window.location.href = url;
    
public void GenerateReportMainMonthly()
        
            _isDaily = false;
            GenerateReportMain();
        

【问题讨论】:

【参考方案1】:

您似乎正在控制器中运行后台任务。这通常是一个坏主意 (see this SO answer),因为您可能会发现您的服务器进程已在中途被终止,您的客户端将不得不以某种方式处理它。

如果您绝对必须在控制器中运行较长的进程并且无法将其提取到某种后台工作程序中,您可以选择类似this SO answer 建议的方法。实施将根据您的设置以及您愿意/能够实现的程度而有所不同,但基本内容将保持不变:

    您立即调用以启动您的长操作并返回工作 ID 以供参考 您的后端将处理任务并相应地更新状态 您的客户将定期检查状态并在报告作业完成时执行您想要的行为。

如果我要解决这个问题,我会尽量避免定期轮询,而是选择本博文中描述的 SignalR 更新(例如,this is not mine,我只是用谷歌搜索了它)。

【讨论】:

以上是关于对 Controller 函数进行异步调用 (void)。无法将控制权交还给 UI的主要内容,如果未能解决你的问题,请参考以下文章

使用 redux-saga 对 redux store 进行异步调用

异步查询回调函数调用

使用 axios、TypeScript 模板和异步函数对 VueJS 进行单元测试

如果我不等待它,是不是保证从 Mvc.Controller 操作方法调用的异步方法完成? [复制]

多个异步请求调用一个回调函数

Javascript - 异步调用后同步