C# 如何为应用程序_BeginRequest中第一个命中Web服务器的请求执行部分代码?
我想记录第一个命中我的服务器的请求,因此我在Global.asax.cs中编写了这部分代码C# 如何为应用程序_BeginRequest中第一个命中Web服务器的请求执行部分代码?,c#,asp.net-mvc,multithreading,C#,Asp.net Mvc,Multithreading,我想记录第一个命中我的服务器的请求,因此我在Global.asax.cs中编写了这部分代码 private bool _startupHasBeenLogged = false; protected void Application_BeginRequest(object sender, EventArgs e) { if (!_startupHasBeenLogged) { DoLog(); _startupHasBeenLogged = tru
private bool _startupHasBeenLogged = false;
protected void Application_BeginRequest(object sender, EventArgs e)
{
if (!_startupHasBeenLogged)
{
DoLog();
_startupHasBeenLogged = true;
}
}
问题是我得到了前5个或6个请求的日志。我猜服务器会一次收到多个请求,因此DoLog会在布尔值变为真之前多次命中
我已尝试使用联锁:
int running = 0;
protected void Application_BeginRequest(object sender, EventArgs e)
{
if (Interlocked.CompareExchange(ref running, 1, 0) != 0) return;
if (!_startupHasBeenLogged)
{
_startupHasBeenLogged = true;
DoLog();
}
Interlocked.Exchange(ref running, 0);
}
和Monitor.TryEnter:
private static readonly object _lock = new object();
protected void Application_BeginRequest(object sender, EventArgs e)
{
if (Monitor.TryEnter(_lock))
{
try
{
if (!_startupHasBeenLogged)
{
_startupHasBeenLogged = true;
DoLog();
}
}
finally
{
Monitor.Exit(_lock);
}
}
}
但每次,日志都会触发5或6次
那么,对于Web服务器中的第一个请求,如何只运行一次代码呢
编辑解决方案:
我没有注意到的细节是,StartupHasnlog有多个实例。这把锁很好用。只需声明一个静态bool
private static bool _startupHasBeenLogged = false;
。我认为这是一个对象池。我觉得这个设计令人震惊。它没有实际用途
不要在应用程序对象中放置状态。创建一个具有静态变量的单独类。每个AppDomain都是全局的。ASP.NET不能搞乱它们
当然,也可能存在多个应用程序域同时运行的情况,但这种情况很少见。例如,在回收池时会发生这种情况。控制器上有以下覆盖
protected override void OnActionExecuting(ActionExecutingContext filterContext)
protected override void OnActionExecuted(ActionExecutedContext filterContext)
我以前在baseController类中使用过它 为什么不改为使用应用程序启动事件?在无效会话启动()事件上应用上述逻辑?我想记录一个请求,而请求对象在应用程序或会话开始时不可用。是否使用IIS?如果是这样,您是否有可能拥有多个工作进程?有关HttpApplication池的详细信息;“我从来都不知道,”马克·布莱克特说,“没有人知道,这很愚蠢。