Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何为应用程序_BeginRequest中第一个命中Web服务器的请求执行部分代码?_C#_Asp.net Mvc_Multithreading - Fatal编程技术网

C# 如何为应用程序_BeginRequest中第一个命中Web服务器的请求执行部分代码?

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

我想记录第一个命中我的服务器的请求,因此我在Global.asax.cs中编写了这部分代码

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池的详细信息;“我从来都不知道,”马克·布莱克特说,“没有人知道,这很愚蠢。