ASP.NET中的请求或服务器是静态类实例吗?

在ASP.NET网站上,每个Web请求都是唯一的静态类,还是在GC决定处理它们时,在需要时进行实例化,并进行GC处理?

我问的原因是因为我之前在C#中编写了一些静态类,行为与我预期的不同。 我会期望静态类对每个请求是唯一的,但似乎并不是这样的情况。

如果他们不是每个请求都是唯一的,有没有办法让他们成为?

更新:
driis给我的答案正是我所需要的。 我已经使用了一个单独的类,但是它使用了一个静态实例,因此即使用户不同,在这个请求之间也是共享的,在这种情况下是不好的。 使用HttpContext.Current.Items完美地解决了我的问题。 对于将来会遇到这个问题的人来说,这里是我的实现,简化和缩短,以便于理解模式:

 using System.Collections; using System.Web; public class GloballyAccessibleClass { private GloballyAccessibleClass() { } public static GloballyAccessibleClass Instance { get { IDictionary items = HttpContext.Current.Items; if(!items.Contains("TheInstance")) { items["TheInstance"] = new GloballyAccessibleClass(); } return items["TheInstance"] as GloballyAccessibleClass; } } } 

您的静态类和静态实例字段在应用程序的所有请求之间共享,并具有与应用程序域相同的生命周期。 因此,使用静态实例时应该小心,因为可能有同步问题等。 还要记住,在应用程序池被回收之前,静态实例不会被GC化,因此静态实例引用的所有内容都不会被GC化。 这可能会导致内存使用问题。

如果您需要与请求具有相同生命周期的实例,我会build议使用HttpContext.Current.Items集合。 这是devise意图是一个存储你需要通过请求的东西的地方。 为了更好的devise和可读性,您可以使用Singleton模式来帮助您pipe理这些项目。 只需创build一个Singleton类,将其实例存储在HttpContext.Current.Items 。 (在我的ASP.NET通用库中,我有一个通用的SingletonRequest类用于此目的)。

静态成员只有当前工作进程的范围,所以它与请求无关,因为不同的请求可能会或可能不会被同一个工作进程处理。

  • 为了与特定用户和跨请求共享数据,请使用HttpContext.Current.Session。
  • 为了在特定请求中共享数据,请使用HttpContext.Current.Items。
  • 为了在整个应用程序之间共享数据,请为此写入一个机制,或者configurationIIS以使用单个进程并编写单例/使用应用程序。

顺便说一下,工作进程的默认数量是1,所以这就是为什么networking充满了人们认为静态成员具有整个应用程序的范围。

由于types包含在应用程序域中,因此只要应用程序域未被回收,或者请求获得了不同的应用程序域的服务,我就希望存在静态类。

我可以想出几种方法来使特定于特定请求的对象取决于您想要做什么,例如,您可以在Application.BeginRequest中实例化对象,然后将其存储在HttpRequest对象中,以便它可以被所有对象访问请求处理pipe道。

如果他们不是每个请求都是唯一的,有没有办法让他们成为?

不。 静态成员由ASP.NET进程拥有,并由Web应用程序的所有用户共享。 您需要转向其他会话pipe理技术,例如会话variables。

通常情况下,静态方法,属性和类在Application级通用。 只要应用程序存在,它们就被共享。

您可以使用ThreadStatic属性指定不同的行为。 在这种情况下,他们将特定于当前的线程,我认为这是针对每个请求的。
我不会build议这个,因为它似乎过于复杂。

你可以使用HttpContext.Current.Items为一个请求设置东西,或者HttpContext.Current.Session为一个用户设置东西(跨请求)。

一般来说,除非你必须使用Server.Transfer之类的东西,否则最好的方法就是创build一个事物,然后通过方法调用显式地传递它们。