gpt4 book ai didi

c# - 如何在 Application_BeginRequest 中为第一个访问网络服务器的请求执行部分代码?

转载 作者:太空宇宙 更新时间:2023-11-03 23:32:03 24 4
gpt4 key购买 nike

我想记录第一个到达我的服务器的请求,所以我在我的 Global.asax.cs 中编写了那部分代码

private bool _startupHasBeenLogged = false;
protected void Application_BeginRequest(object sender, EventArgs e)
{
if (!_startupHasBeenLogged)
{
DoLog();
_startupHasBeenLogged = true;
}
}

问题是我得到了前 5 或 6 个请求的日志。我猜服务器一次收到多个请求,所以 DoLog 在 bool 值变为真之前多次命中。

我试过使用联锁:

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 次。

那么如何在网络服务器中为第一个请求只运行一次代码?

编辑解决方案:

我错过的细节是 the Application is instanciated multiple times ,所以 _startupHasBeenLogged 有多个实例。锁工作正常。只需声明一个静态 bool

private static bool _startupHasBeenLogged = false;

最佳答案

ASP.NET instantiates your HttpApplication derived class multiple times .我认为这是一个对象池。我觉得这个设计令人震惊。它没有实际用途。

不要将状态放在应用程序对象中。创建一个具有静态变量的单独类。每个 AppDomain 都是全局的。 ASP.NET 无法与它们混为一谈。

当然,可能会出现多个应用程序域同时运行的情况,但这种情况很少见。例如,在回收池时会发生这种情况。

关于c# - 如何在 Application_BeginRequest 中为第一个访问网络服务器的请求执行部分代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31837363/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com