MVC4 异步控制器操作未完成
本文关键字:操作 未完成 控制器 异步控制 异步 MVC4 | 更新日期: 2023-09-27 18:31:53
我有一个由jquery ajax请求调用的异步操作:
视图:
$.ajax({
url: "@Url.Action("StartVerification", "Devices")",
global: false,
data: JSON.stringify(machineIds),
contentType: 'application/json',
type: 'POST'
...
控制器:
[HttpPost]
[SessionExpireFilter(Order = 1)]
[CheckPermissions(Order = 2)]
[AjaxMessagesFilter(Order = 3)]
[AsyncTimeout(30000, Order = 4)]
[HandleError(ExceptionType = typeof(TimeoutException), View = "TimeoutError", Order = 5)]
public async Task<JsonResult> StartVerification(ICollection<Machine> machines)
{
Dictionary<int, bool> collection = new Dictionary<int, bool>();
foreach (var machine in machines)
{
Response response = new Response();
try
{
response = await this.deviceRepository.StartVerification(machine);
}
catch (Exception ex)
{
response.Success = false;
}
collection.Add(machine.MachineID, response.Success);
}
return this.Json(collection.ToDictionary(x => x.Key.ToString(), y => y.Value));
}
网络服务调用:
public async Task<Response> StartVerification(Machine machine, CancellationToken cancelToken = default(CancellationToken))
{
WebService WebServiceForTask = WebServiceFactory.NewInstance;
return await Task.Run(() => WebServiceForTask.StartVerificationForWebSite(machine.SiteID, machine.MachineID));
}
我遇到的问题是,当执行 StartVerification 操作时,该操作会调用然后查询 Web 服务。对该结果的查询可能需要几秒钟的时间,在此期间,用户可以按其浏览器的刷新按钮。处理这种情况并简单地中止呼叫等的最佳方法是什么。
编辑:也许我问错了问题。这里的问题是,当我开始验证并点击刷新页面 F5 时,页面不会刷新,直到我收到来自 Web 服务的响应......看起来动作不是异步运行的。我希望它能够工作,以便如果已经调用了控制器操作并等待来自 Web 服务的响应,我仍然应该能够简单地浏览离开我正在调用操作的页面。
处理这种情况并简单地中止呼叫等的最佳方法是什么
您可以在启动 AJAX 请求之前订阅 onbeforeunload
事件:
window.onbeforeunload = function() {
return 'There''s an ongoing operation. If you leave this page you might lose some data';
};
并在 AJAX 调用完成后删除对此事件的订阅。
由于您有一个 AsyncTimeout
属性,因此您应该采用表示该超时的CancellationToken
。
还有另一个CancellationToken
表示用户提前断开连接(Response.ClientDisconnectedToken
)。但是,目前ClientDisconnectedToken
存在竞争条件,因此我不建议将其与当前版本的 ASP.NET(4.5)一起使用。现在最好的策略是遵守AsyncTimeout
,忽略早期客户端断开连接。
但是,如果您确实要检测客户端断开连接,则可以定期轮询Response.IsClientConnected
。