我想创建一个简单的全局变量,ActionFilterAttribute
它会告诉我请求的资源以及运行所需的时间。这是到目前为止的代码:
public class APITraceAttribute : ActionFilterAttribute
{
private readonly Stopwatch timer;
public APITraceAttribute()
{
timer = new Stopwatch();
}
public override void OnActionExecuting(HttpActionContext actionContext)
{
timer.Restart();
base.OnActionExecuting(actionContext);
}
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
timer.Stop();
trace(actionExecutedContext.ActionContext, timer.Elapsed);
base.OnActionExecuted(actionExecutedContext);
}
private static void trace(HttpActionContext actionContext, TimeSpan duration)
{
HttpMethod method = actionContext.Request.Method;
string path = actionContext.Request.RequestUri.PathAndQuery;
string controllerName = actionContext.ControllerContext.ControllerDescriptor.ControllerName;
string actionName = actionContext.ActionDescriptor.ActionName;
double totalSeconds = duration.TotalSeconds;
ILogger logger = new Logger("trace");
logger.Trace("{0} {1}: {2}Controller.{3} ({4:N4} seconds)...", method, path, controllerName, actionName, totalSeconds);
}
}
如您所见,我使用 aStopwatch
作为Restart
动作开始和Stop
动作结束时的支持字段。我不需要很高的精度,所以这很好。
但是,我通过编辑/App_Start/WebApiConfig.cs
文件来连接它以运行所有请求:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Filters.Add(new APITraceAttribute());
}
}
我注意到这需要一个构造属性。这让我担心它将全面重用相同的属性实例,并且两个同时处理的请求可能会尝试使用相同的Stopwatch
实例。是这样吗?如何确保每个请求都有自己的实例Stopwatch
?