如何使用ActionFilterAttribute来记录运行时间
本文关键字:记录 运行时间 ActionFilterAttribute 何使用 | 更新日期: 2023-09-27 17:51:03
我创建了一个操作过滤器,用于测量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);
}
}
但是,操作筛选器充当singleton,因此当OnActionExecuted
运行时,我不能确定_logger
和_timer
是否与为相同操作OnActionExecuting
创建的对应。
例如。
- Action Foo1开始执行。
_logger = "logger1"
、_timer = "timer1"
- Action Foo2开始执行。
_logger = "logger2"
、_timer = "timer2"
(它们被覆盖( - Action Foo1结束执行。它停止计时器并记录无意义的运行时间(end1-start2(
问题:有没有办法让我知道OnActionExecuted
中它对应的OnActionExecuting
?如果有一些操作的唯一标识符,我可以将其用作Dictionary的键,以存储任何与操作相关的对象,如记录器和计时器。有吗?或者其他解决方案?
就Web API而言,System.Web.HttpContext.Current
并不总是有保证的。这取决于您是否使用Web API自托管。这就是在重写System.Web.Http.Filters.ActionFilterAttribute.OnActionExecuting
时,您不会在HttpActionContext
参数上获得httpcontext属性的主要原因(在AspNetMVC中,您会获得(。
最好的方法是使用actionContext.Request.Properties
字典。
也可以在这里检查这个答案
系统。网状物HttpContext。现在的Items是一个按请求的缓存存储
您可以安全地在OnBeforeAction方法的Items中添加计时器对象,并从OnAfterAction方法中的Items检索此计时器对象