由于没有一个答案被标记为答案,我认为没有人真正解决过相关的问题或问题......
在 ASP.NET 中,您有 Global 或 HttpApplication。这样做的方式是 IIS 将缓存您的“应用程序”的实例(即您的 Global 类的实例)。通常(IIS 中的默认设置)您最多可以拥有 10 个 Global 实例,IIS 将选择其中任何一个实例来满足请求。
此外,请记住,在任何给定时刻都可能有多个请求。这意味着将使用您的 Global 类的多个实例。这些实例可能是先前实例化和缓存的实例,也可能是新实例(取决于您的 IIS 服务器所看到的负载)。
IIS 还具有应用程序池和工作进程的概念。 Worker 进程将托管您的应用程序和 Global 类的所有实例(如前所述)。所以这转化为一个应用程序域(在 .NET 术语中)。
只是在继续之前重新设置......
您的 Global 类的多个实例将存在于您的应用程序的 Worker 进程中(在 IIS 中)。每一个都等待 IIS 调用以满足请求。 IIS 将选择这些实例中的任何一个。它们实际上是 IIS 缓存的线程,每个线程都有一个 Global 类的实例。当一个请求进来时,这些线程之一被调用来处理请求-响应周期。如果多个请求同时到达,则将调用多个线程(每个线程都包含一个 Global 类的实例)来满足每个请求。
继续……
由于每个应用程序域只有一个静态类的实例,因此您将有效地在所有(最多 10 个)Global 实例之间共享您的类的一个实例。这是一个坏主意,因为当多个同时请求到达您的服务器时,它们要么被阻塞(如果您的类的方法使用锁),要么线程将互相踩踏。换句话说,这种方法本质上不是线程安全的,如果您使用线程同步原语使其成为线程安全的,那么您将不必要地阻塞线程,对您的 Web 应用程序的性能和可伸缩性产生负面影响,而没有任何收益。
真正的解决方案(我在所有 ASP.NET 应用程序中都使用它)是为每个 Global 实例创建一个 BLL 或 DAL 实例(视情况而定)。这将确保以下几点:
1. 多线程不是问题,因为 IIS 保证在任何给定时间每个 Global 实例都有一个请求-响应。所以你的代码本质上是线程安全的。
2. 在任何给定时刻,您最多只能有 10 个 BLL/DAL 实例启动并运行,确保您不会不断创建和处置(通常)大型对象的实例以满足每个请求,这在繁忙的网站上是巨大的
3. 由于上面的#2,你得到了非常好的性能。
您必须确保您的 BLL/DAL 真正是无状态的,或者您必须在每个请求-响应周期开始时重置任何状态。您可以使用 Global 中的 BeginRequest 事件来完成您需要的操作。
如果你走这条路,请务必阅读我的博客文章
Instantiating Business Layers – ASP.NET