加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 如何使用ActionFilterAttribute记录运行时间?

发布时间:2020-12-16 02:00:51 所属栏目:百科 来源:网络整理
导读:我创建了一个动作过滤器,用于测量Web API v2中每个操作的运行时间. public class RunningTimeAttribute : ActionFilterAttribute { private readonly ILogFactory _logFactory; private readonly ITimerFactory _timerFactory; private ITimer _timer; priva
我创建了一个动作过滤器,用于测量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和_timer是否对应于为同一动作OnActionExecuting创建的那些.

例如.

>动作Foo1开始执行. _logger =“logger1”,_ timer =“timer1”.
>动作Foo2开始执行. _logger =“logger2”,_ timer =“timer2”(它们被覆盖)
>动作Foo1结束执行.它会停止计时器并记录经过的时间,这是无意义的(end1-start2).

问题:OnActionExecuted中是否有一种方式可以识别它对应的OnActionExecuting?如果有一些唯一的动作标识符,我可以将它用作Dictionary的一个键来存储任何与动作相关的对象,如记录器和定时器.有没有?或其他一些解决方案?

解决方法

就Web API而言,并不总能保证System.Web.HttpContext.Current.这取决于您是否使用Web API Self托管.这是重写System.Web.Http.Filters.ActionFilterAttribute.OnActionExecuting时你没有在HttpActionContext参数上获得httpcontext属性的主要原因(在你做的AspNet MVC中).

执行相同操作的最佳方法是actionContext.Request.Properties字典.

检查这个答案here

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读