我创建了一个操作过滤器,用于测量 Web API v2 中每个操作的运行时间。
public class RunningTimeAttribute : ActionFilterAttribute
{
private readonly ILogFactory _logFactory;
private readonly ITimerFactory _timerFactory;
private ITimer _timer;
private ILogger _logger;
public RunningTimeAttribute(ILogFactory logFactory, ITimerFactory timerFactory) {
if(logFactory == null)
throw new ArgumentNullException("logFactory");
if(timerFactory == null)
throw new ArgumentNullException("timerFactory");
_logFactory = logFactory;
_timerFactory = timerFactory;
}
public override void OnActionExecuting(HttpActionContext actionContext) {
base.OnActionExecuting(actionContext);
OnBeforeAction(actionContext);
}
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) {
OnAfterAction(actionExecutedContext);
base.OnActionExecuted(actionExecutedContext);
}
private void OnBeforeAction(HttpActionContext actionContext) {
var controllerName = actionContext.ControllerContext.Controller.GetType().FullName;
var actionName = actionContext.ActionDescriptor.ActionName;
_logger = _logFactory.Create(controllerName);
_logger.Trace("Action \"{0}\" begins execution", actionName);
_timer = _timerFactory.Create();
_timer.Start();
}
private void OnAfterAction(HttpActionExecutedContext actionExecutedContext) {
var actionName = actionExecutedContext.ActionContext.ActionDescriptor.ActionName;
_timer.Stop();
_logger.Trace("Time elapsed for action \"{0}\": {1} msec", actionName, _timer.ElapsedMilliseconds);
}
}
然而,动作过滤器充当单例,所以当OnActionExecuted
运行,我不能确定_logger
and _timer
对应于为同样的动作OnActionExecuting
.
Eg.
- 动作 Foo1 开始执行。
_logger = "logger1"
, _timer = "timer1"
.
- 动作 Foo2 开始执行。
_logger = "logger2"
, _timer = "timer2"
(他们被覆盖)
- 动作 Foo1 结束执行。它停止计时器并记录经过的时间,这是无意义的(end1-start2)。
Question: 有什么办法可以知道吗OnActionExecuted
到哪个OnActionExecuting
它对应?如果操作有一些唯一标识符,我可以将其用作字典的键来存储任何与操作相关的对象,例如记录器和计时器。有没有?或者其他解决方案?
就 Web API 而言System.Web.HttpContext.Current
并不总是有保证。这取决于您是否使用 Web API 自托管。这是覆盖时的主要原因System.Web.Http.Filters.ActionFilterAttribute.OnActionExecuting
您没有获得 httpcontext 属性HttpActionContext
参数(在 AspNet MVC 中你可以这样做)。
做同样的事情的最好方法是actionContext.Request.Properties
字典。
另请检查这个答案here
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)