如何在ASP.NET MVC中中止操作

我想停止服务器端jQuery.ajax方法调用的操作。 我可以在客户端使用$.ajax.abort()方法停止Ajax请求,但不能在服务器端停止。

更新:

我使用异步操作而不是同步操作,但我没有得到我想要的! 如您所知,服务器无法同时处理多个请求,导致每个请求必须等到上一个请求完成,即使先前的请求被$ .Ajax.Abort()方法取消。 我知道如果我使用[SessionState(System.Web.SessionState.SessionStateBehavior.ReadOnly)]属性它几乎我想要但它不满足我。

最重要的是我想在用户端中止服务器端的处理方法。 而已 :)

您可能希望查看使用以下类型的控制器在ASP.NET MVC中使用异步控制器

并且看看这篇文章是否也帮助你取消异步Web服务调用 ,抱歉我这次不能给出任何代码示例。

我创建了一个示例作为概念certificate,以表明您可以取消服务器端请求。 我的github异步取消示例

如果您通过代码调用其他站点,则有两种选择,具体取决于您的目标框架以及您要使用的方法。 我在这里提供了参考资料供你审查:

WebRequest.BeginGetResponse用于.Net 4.0 HttpClient ,用于.Net 4.5,该类有一个取消所有待处理请求的方法。

希望这能为您提供足够的信息来实现您的目标。

这是一个示例后端:

 [HttpGet] public List Get(){ var gotResult = false; var result = new List(); var tokenSource2 = new CancellationTokenSource(); CancellationToken ct = tokenSource2.Token; Task.Factory.StartNew(() => { // Do something with cancelation token to break current operation result = SomeWhere.GetSomethingReallySlow(); gotResult = true; }, ct); while (!gotResult) { // When you call abort Response.IsClientConnected will = false if (!Response.IsClientConnected) { tokenSource2.Cancel(); return result; } Thread.Sleep(100); } return result; } 

使用Javascript:

 var promise = $.post("/Somewhere") setTimeout(function(){promise.abort()}, 1000) 

希望我不要迟到。

我们已经在IE中看到了问题,其中中止的请求仍然被转发到控制器操作 – 但是,在我们的日志和用户活动条目中报告了剥离的参数,这导致了不同的错误。

我已经使用如下filter解决了这个问题

 using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using TWV.Infrastructure; using TWV.Models; namespace TWV.Controllers { public class TerminateOnAbortAttribute : FilterAttribute, IActionFilter { public void OnActionExecuting(ActionExecutingContext filterContext) { // IE does not always terminate when ajax request has been aborted - however, the input stream gets wiped // The content length - stays the same, and thus we can determine if the request has been aborted long contentLength = filterContext.HttpContext.Request.ContentLength; long inputLength = filterContext.HttpContext.Request.InputStream.Length; bool isAborted = contentLength > 0 && inputLength == 0; if (isAborted) { filterContext.Result = new EmptyResult(); } } public void OnActionExecuted(ActionExecutedContext filterContext) { // Do nothing } } } 

一个简单的解决方案是使用类似下面的内容。 我用它来取消长时间运行的任务(特别是生成数千个通知)。 我也使用相同的方法来轮询进度并通过AJAX更新进度条。 此外,这几乎适用于任何版本的MVC,并不依赖于.NET的新function

 public class MyController : Controller { private static m_CancelAction = false; public string CancelAction() { m_CancelAction = true; return "ok"; } public string LongRunningAction() { while(...) { Dosomething (ie Send email, notification, write to file, etc) if(m_CancelAction) { m_CancelAction = false; break; return "aborted"; } } return "ok"; } }