C# ASP.Net MVC异步控制器日志请求处理时间
我需要获得asp.net MVC的请求处理时间。我使用IHttpModule订阅onBeginRequest和onEndRequest事件。对于同步控制器,它工作得很好,但对于异步控制器,它返回错误的结果(例如,当实时时间约为2min时,返回20ms)。我怎样才能以一般方式获得AsyncController的请求处理时间(不为每个异步操作在ActionAsync/ActionCompleted中编写传统代码) 公共类TrackRequestModule:RequestProcessingModuleBase,IHttpModule { public const string BeginRequestTimeKey=“beginRequestTime”; 公共void Init(HttpApplication上下文) { if(上下文==null) { 抛出新的ArgumentNullException(“上下文”); } context.BeginRequest+=onBeginRequest; context.EndRequest+=onEndRequest; } 私有void onEndRequest(对象发送方,事件参数e) { InvokeHandler(发送方,OnEndRequest); } 私有void onBeginRequest(对象发送方,事件参数e) { InvokeHandler(发送方,OnBeginRequest); } 公共void OnBeginRequest(HttpContextBase上下文) { context.Items[BeginRequestTimeKey]=DateTime.Now.ToLocalTime(); } 公共无效OnEndRequest(HttpContextBase上下文) { var beginRequestTime=(DateTime)context.Items[BeginRequestTimeKey]; TimeSpan elapsedTime=DateTime.Now.ToLocalTime()-beginRequestTime; var info=新的请求数据 { 开始时间=开始请求时间, elapsedTime毫秒=elapsedTime.毫秒, Url=context.Request.Url.AbsoluteUri, Data=GetRequestData(context.Request) }; QueueUserWorkItem(logRequestInfo,info); } public void Dispose(){} 私有void logRequestInfo(对象状态) { var info=(RequestData)状态; var queryStore=ObjectBuilder.Instance.Resolve(); SaveRequestTrackingData(info.BeginTime、info.elapsedtimemissions、info.Url、info.Data); } 私有密封类请求数据 { 公共日期时间开始时间{get;set;} public int elapsedtimemissions{get;set;} 公共字符串Url{get;set;} 公共字符串数据{get;set;} } }C# ASP.Net MVC异步控制器日志请求处理时间,c#,asp.net,asp.net-mvc-3,ihttpmodule,asynccontroller,C#,Asp.net,Asp.net Mvc 3,Ihttpmodule,Asynccontroller,我需要获得asp.net MVC的请求处理时间。我使用IHttpModule订阅onBeginRequest和onEndRequest事件。对于同步控制器,它工作得很好,但对于异步控制器,它返回错误的结果(例如,当实时时间约为2min时,返回20ms)。我怎样才能以一般方式获得AsyncController的请求处理时间(不为每个异步操作在ActionAsync/ActionCompleted中编写传统代码) 公共类TrackRequestModule:RequestProcessingModu
这很奇怪。通常情况下,这种情况应该是可行的。不幸的是,您还没有显示代码,因此很难说您可能做错了什么 此外,我无法复制它。以下是我编写用来测试的模块:
public class MeasureModule : IHttpModule
{
private static readonly ReaderWriterLockSlim _gateway = new ReaderWriterLockSlim();
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.BeginRequest += (sender, e) =>
{
var app = (sender as HttpApplication);
var watch = Stopwatch.StartNew();
app.Context.Items["watch"] = watch;
};
context.EndRequest += (sender, e) =>
{
var app = (sender as HttpApplication);
var watch = app.Context.Items["watch"] as Stopwatch;
watch.Stop();
var url = app.Context.Request.Url.AbsoluteUri;
var message = string.Format("url: {0}, time: {1}ms", url, watch.ElapsedMilliseconds);
var log = HostingEnvironment.MapPath("~/log.txt");
_gateway.EnterWriteLock();
try
{
File.AppendAllLines(log, new[] { message });
}
finally
{
_gateway.ExitWriteLock();
}
};
}
}
我在我的web.config中注册了该模块(我在Cassini下进行了测试,如果您打算使用IIS 7,则必须在相应的
部分注册该模块):
然后,我向以下URL发出了两个并行HTTP请求:
/home/index
/home/indexsync
url: http://localhost:14953/home/index, time: 5047ms
url: http://localhost:14953/home/indexsync, time: 5005ms
如您所见,HTTP模块正确地测量了异步和同步操作的执行时间
那么是什么原因呢
顺便说一句,您可以结帐,并确保您的场景中没有车轮改造。谢谢!它起作用了。在我的版本中,我把DateTime.Now放在了上下文中的beginrequest和onEndRequest elapsedTime=DateTime.Now-;如果你解释我的版本是错的,那就太酷了。对不起,我的英语,再次感谢。你必须显示你的代码,这样我才能解释为什么你的版本是错误的。目前你还没有显示任何代码,因此我很难告诉你你做错了什么。以下是你做错的地方:
elapsedtimemilosses=elapsedTime.millises
。它应该是elapsedtimemissions=elapsedTime.totalMillissions
。毫秒
将永远不会大于1000:-)
<httpModules>
<add name="measure" type="MvcApplication.Modules.MeasureModule, MvcApplication" />
</httpModules>
[SessionState(SessionStateBehavior.Disabled)]
public class HomeController : AsyncController
{
public ActionResult IndexSync()
{
Thread.Sleep(5000);
return Content("completed", "text/plain");
}
public void IndexAsync()
{
AsyncManager.OutstandingOperations.Increment();
Task.Factory.StartNew(() =>
{
Thread.Sleep(5000);
AsyncManager.OutstandingOperations.Decrement();
});
}
public ActionResult IndexCompleted()
{
return Content("completed", "text/plain");
}
}
url: http://localhost:14953/home/index, time: 5047ms
url: http://localhost:14953/home/indexsync, time: 5005ms