有没有办法在ASP.NET Web API beta中找出HTTP请求是否被取消(由于任何其他原因被用户中止)?我正在寻找机会获得一种即取即用的取消标记,表示请求已中止,因此长时间运行的操作也应中止。ASP.NET Web API +长时间运行操作取消
可能的相关问题 - CancellationTokenModelBinder类的用例。为取消令牌设置单独的绑定程序的原因是什么?
有没有办法在ASP.NET Web API beta中找出HTTP请求是否被取消(由于任何其他原因被用户中止)?我正在寻找机会获得一种即取即用的取消标记,表示请求已中止,因此长时间运行的操作也应中止。ASP.NET Web API +长时间运行操作取消
可能的相关问题 - CancellationTokenModelBinder类的用例。为取消令牌设置单独的绑定程序的原因是什么?
您可以不时查看Response.IsClientConnected
以查看浏览器是否仍连接到服务器。
我想总结一下。似乎工作的唯一方法是检查Response.IsClientConnected。 关于到底是怎么回事幕后走向台前这里是一些技术细节: here和here 这种方法有一定的缺陷:只能在IIS(没有自托管,没有开发服务器)
最后我想出了基于IsClientConnected到Web API控制器下面这段代码注入的CancellationToken:
public class ConnectionAbortTokenAttribute : System.Web.Http.Filters.ActionFilterAttribute
{
private readonly string _paramName;
private Timer _timer;
private CancellationTokenSource _tokenSource;
private CancellationToken _token;
public ConnectionAbortTokenAttribute(string paramName)
{
_paramName = paramName;
}
public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
{
object value;
if (!actionContext.ActionArguments.TryGetValue(_paramName, out value))
{
// no args with defined name found
base.OnActionExecuting(actionContext);
return;
}
var context = HttpContext.Current;
if (context == null)
{
// consider the self-hosting case (?)
base.OnActionExecuting(actionContext);
return;
}
_tokenSource = new CancellationTokenSource();
_token = _tokenSource.Token;
// inject
actionContext.ActionArguments[_paramName] = _token;
// stop timer on client disconnect
_token.Register(() => _timer.Dispose());
_timer = new Timer
(
state =>
{
if (!context.Response.IsClientConnected)
{
_tokenSource.Cancel();
}
}, null, 0, 1000 // check each second. Opts: make configurable; increase/decrease.
);
base.OnActionExecuting(actionContext);
}
/*
* Is this guaranteed to be called?
*
*
*/
public override void OnActionExecuted(System.Web.Http.Filters.HttpActionExecutedContext actionExecutedContext)
{
if(_timer != null)
_timer.Dispose();
if(_tokenSource != null)
_tokenSource.Dispose();
base.OnActionExecuted(actionExecutedContext);
}
}
也有一个选项可以使用SignalR和类似的解决方案,但它们对我来说有点超出范围。 – 2012-03-19 15:51:52
如果您将CancellationToken添加到控制器方法中,它将被框架自动注入,并且当客户端调用xhr.abort()时,令牌将自动取消
类似的东西来
public Task<string> Get(CancellationToken cancellationToken = default(CancellationToken))
对于MVC,你也可以参考
HttpContext.Current.Response.IsClientConnected
HttpContext.Response.ClientDisconnectedToken
对于.NetCore
services.AddTransient<ICustomInterface>(provider => {
var accessor = provider.GetService<IHttpContextAccessor>);
accessor.HttpContext.RequestAborted;
});
这似乎是从ASP.NET MVC堆栈,而不是从ASP.NET MVC Web API。如果错了,请纠正我。 – 2012-03-19 09:02:13
这是来自核心ASP.Net引擎。只适用于IIS集成管道(不是VS调试模式)。 MSDN涵盖了一个很好的文档: http://msdn.microsoft.com/en-us/library/system.web.httpresponse.isclientconnected.aspx – 2012-03-19 09:22:10
谢谢你的建议。这似乎是唯一的选择,我可能会基于此构建解决方案。 – 2012-03-19 15:31:53