ASP.NET / WCF / IIS 中静态变量的范围是啥?

Posted

技术标签:

【中文标题】ASP.NET / WCF / IIS 中静态变量的范围是啥?【英文标题】:What is the scope of a static variable in ASP.NET / WCF / IIS?ASP.NET / WCF / IIS 中静态变量的范围是什么? 【发布时间】:2019-12-18 10:14:39 【问题描述】:

这里有两个问题都得到了高度评​​价,但看似矛盾的答案。

静态变量的实际作用域是什么?

就我而言,假设我有一个在 IIS 下运行的 WCF 服务。前面有负载平衡器的几台服务器。每台服务器上有一个站点,还有一个应用程序池。假设在实现服务的类中存储了一个静态变量。

变量是否只在工作进程中持续存在?应用程序池?服务器?我试图研究它,但在这里找到了两个相互竞争的答案。

在这篇文章下: IIS app pools, worker processes, app domains

回复说“每个工作进程都是运行您的站点的不同程序,有自己的 [自己的?] 静态变量”

然而在这个帖子下: Lifetime of ASP.NET Static Variable

回复说“静态变量是每个池”

也许我只是不明白这些帖子,但它们似乎相互矛盾?

当我检查时,我似乎有几个工作进程正在运行。因此我的问题。

任何帮助将不胜感激。我试图重构一些东西而不使用静态变量,因为它看起来很冒险并且暴露了并发问题,但是我很不舒服在不了解当前行为的情况下提出更改。谢谢!

【问题讨论】:

看看这个thread 它解释了什么是 ASP.NET 中的静态变量范围 那么它是每个工作进程的吗? 【参考方案1】:

静态变量在应用程序域的生命周期内持续存在。所以有两件事会重置你的静态变量是应用程序域重新启动或使用新类

每个应用程序池可以有多个工作进程,

每个工作进程将运行不同的应用程序实例。

应用程序的每个实例都有一个单独的 AppDomain - 每个应用程序实例一个。

当发生以下任何情况时 IIS 重新启动您的 asp.net 应用程序时,静态变量会丢失

    池决定需要重新编译。 您打开 app_offline.htm 文件 手动重启应用程序池 池已达到服务器上定义的一些限制并重新启动。 重启iis

静态变量不是线程安全的,如果你从不同的线程访问它们,你需要使用lock关键字。

由于应用重启会重置您的静态变量,并且您希望在应用程序生命周期内持久保存数据,因此您应该将数据持久存储在数据库或文件中。您可以使用数据库会话状态模式将每个用户的信息存储在会话状态中。

ASP.NET 应用程序状态/变量将无济于事,因为它们存储在内存中,因此它们不是持久的,因此它们也会在应用程序域重新启动时丢失。

【讨论】:

一个工作进程可以运行多个应用程序实例.. 把它想象成一个迷你 cpu 你可以在你的 cpu 上运行许多 exe,每个 exe 都有一个静态变量 还有一件事......假设我的应用程序是 IIS 上唯一的一个,工作进程能否一次运行我的应用程序的多个实例? 是的,有可能作为工作进程产生线程来启动应用程序域【参考方案2】:

当我们在 web 中定义一个静态字段时,wcf 它将仅与应用程序域限制共享。

【讨论】:

以上是关于ASP.NET / WCF / IIS 中静态变量的范围是啥?的主要内容,如果未能解决你的问题,请参考以下文章

C# WCF 元数据端点不工作(IIS 和 ASP.NET 开发服务器)

从 ASP.NET 应用程序验证 WCF 服务

WCF IIS 服务器 500 错误 检测到在集成的托管管道模式下不适用的ASP.NET设置的解决方法(转)

在没有 IIS 的情况下部署 WCF 服务

ASP.NET 中的 WCF 模拟异常

在 IIS 10 中注册 asp.net