我使用异步 XMLHttpRequest 调用 ASP.net Web 服务中的函数。
当我在 XMLHttpRequest 上调用 abort 方法时,在服务器接收到请求并对其进行处理后,服务器会继续处理请求。
有没有办法停止服务器上的请求处理?
2 回答
一般来说,不,一旦服务器启动,您就无法停止服务器正在处理的请求。毕竟,服务器如何知道请求何时被中止?
这就像您导航到一个网页,但在第一个网页加载之前浏览到另一个网页。至少在某种程度上(任何客户端工作当然不会发生),该初始请求将得到满足。
如果您确实希望停止服务器上长时间运行的操作,则需要对正在调用的服务进行架构,以便它可以支持被中断。一些伪代码:
void MyLongRunningMethod(opId, args)
{
work = GetWork(args)
foreach(workItem in work)
{
DoWork(workItem)
//Has this invocation been aborted?
if(LookUpSet.Contains(opId))
{
LookUpSet.Remove(opId)
return
}
//Or try this:
if(Response.IsClientConnected)
{
HttpContext.Current.Response.End();
return;
}
}
}
void AbortOperation(opId)
{
LookUpSet[opId] = true
}
所以这里的想法是MyLongRunningMethod
定期检查它是否已被中止,如果是则返回。它的目的opId
是唯一的,因此您可以根据附加当前时间或其他内容的客户端的会话 ID 生成它(在 Javascript 中,new Date().getTime()
将为您提供自纪元以来的毫秒数)。
使用这种方法,服务器必须维护状态(LookUpSet
在我的示例中),因此您将需要一些方法来做到这一点,例如数据库或仅将其存储在内存中。该服务还需要进行架构,以便调用 abort 不会使事物处于非工作状态,这当然在很大程度上取决于它的作用。
另一个非常重要的要求是数据可以被拆分并以块的形式处理。这就是允许服务可中断的原因。
最后,如果要中止某个操作,则AbortOperation
必须调用 - 简单地中止 XMLHttpRequest 调用将无济于事,因为该操作将一直持续到完成。
编辑
来自这个问题:ASP.Net:浏览器断开连接时如何停止页面执行?
您还可以检查Response.IsClientConnected
属性以尝试确定调用是否已中止。
一般来说,服务器在尝试向其发送数据之前不会知道客户端已断开连接。请参阅在 .NET 中检测客户端断开连接的最佳实践?并立即检测客户端与服务器套接字的断开连接。
正如 nick_w 所写,一旦服务器启动,您就无法停止服务器正在处理的请求。但是有能力实施解决方案,这将使您能够取消服务器任务。Dino Esposito 有几篇关于如何实现此类事情的精彩文章: 使用 ASP.NET AJAX 取消服务器任务
并在以下文章中实现对服务器的池化 Dino Esposito 描述了如何使用 SignalR 库:使用 SignalR 构建进度条; 长轮询和 SignalR
因此,如果您确实需要取消服务器上的某些任务,这些文章可以作为实施所需解决方案的起点。