我需要获取 asp.net MVC 的请求处理时间。我使用 IHttpModule 订阅 onBeginRequest 和 onEndRequest 事件。对于同步控制器,它工作得很好,但对于异步,它返回错误的结果(例如 20 毫秒,而实时时间约为 2 分钟)。如何以一般方式获得 AsyncController 的请求处理时间(不在 ActionAsync/ActionCompleted 中为每个异步操作编写附加代码)?
public class TrackRequestModule : RequestProcessingModuleBase, IHttpModule
{
public const string BeginRequestTimeKey = "beginRequestTime";
public void Init(HttpApplication context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
context.BeginRequest += onBeginRequest;
context.EndRequest += onEndRequest;
}
private void onEndRequest(object sender, EventArgs e)
{
InvokeHandler(sender, OnEndRequest);
}
private void onBeginRequest(object sender, EventArgs e)
{
InvokeHandler(sender, OnBeginRequest);
}
public void OnBeginRequest(HttpContextBase context)
{
context.Items[BeginRequestTimeKey] = DateTime.Now.ToLocalTime();
}
public void OnEndRequest(HttpContextBase context)
{
var beginRequestTime = (DateTime)context.Items[BeginRequestTimeKey];
TimeSpan elapsedTime = DateTime.Now.ToLocalTime() - beginRequestTime;
var info = new RequestData
{
BeginTime = beginRequestTime,
ElapsedTimeMilliseconds = elapsedTime.Milliseconds,
Url = context.Request.Url.AbsoluteUri,
Data = GetRequestData(context.Request)
};
ThreadPool.QueueUserWorkItem(logRequestInfo, info);
}
public void Dispose() { }
private void logRequestInfo(object state)
{
var info = (RequestData)state;
var queryStore = ObjectBuilder.Instance.Resolve<IRequestTrackingDataQueryStore>();
queryStore.SaveRequestTrackingData(info.BeginTime, info.ElapsedTimeMilliseconds, info.Url, info.Data);
}
private sealed class RequestData
{
public DateTime BeginTime { get; set; }
public int ElapsedTimeMilliseconds { get; set; }
public string Url { get; set; }
public string Data { get; set; }
}
}