¿Las instancias de clases estáticas son únicas para una solicitud o un servidor en ASP.NET?

En un sitio web ASP.NET, ¿las clases estáticas son exclusivas de cada solicitud web, o se crean instancias cada vez que es necesario y GCed cada vez que el GC decide deshacerse de ellas?

La razón por la que pregunto es porque he escrito algunas clases estáticas antes en C # y el comportamiento es diferente de lo que hubiera esperado. Hubiera esperado que las clases estáticas fueran únicas para cada solicitud, pero no parece que sea así.

Si no son exclusivos de cada solicitud, ¿hay alguna forma de permitir que lo estén?

ACTUALIZAR:
La respuesta que driis me dio fue exactamente lo que necesitaba. Ya estaba usando una clase singleton, sin embargo, estaba usando una instancia estática y, por lo tanto, estaba siendo compartida entre las solicitudes, incluso si los usuarios eran diferentes, lo que en este caso era algo malo. Usar HttpContext.Current.Items resuelve mi problema perfectamente. Para cualquiera que tropiece con esta pregunta en el futuro, aquí está mi implementación, simplificada y acortada para que sea fácil entender el patrón:

 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; } } } 

Sus clases estáticas y los campos de instancias estáticas se comparten entre todas las solicitudes a la aplicación y tienen la misma duración que el dominio de la aplicación. Por lo tanto, debe tener cuidado al usar instancias estáticas, ya que puede tener problemas de sincronización y similares. También tenga en cuenta que las instancias estáticas no se someterán a GC antes de que se recicle el grupo de aplicaciones, y por lo tanto, todo lo que se haga referencia a la instancia estática no se someterá a GC. Esto puede conducir a problemas de uso de memoria.

Si necesita una instancia con la misma duración que una solicitud, le sugiero que use la colección HttpContext.Current.Items . Esto es por diseño destinado a ser un lugar para almacenar cosas que necesita a lo largo de la solicitud. Para un mejor diseño y legibilidad, puede usar el patrón Singleton para ayudarlo a administrar estos elementos. Simplemente cree una clase Singleton que almacene su instancia en HttpContext.Current.Items . (En mi biblioteca común para ASP.NET, tengo una clase genérica SingletonRequest para este propósito).

Los miembros estáticos solo tienen un scope del proceso de trabajo actual, por lo que no tiene nada que ver con las solicitudes, ya que diferentes solicitudes pueden o no ser manejadas por el mismo proceso de trabajo.

  • Para compartir datos con un usuario específico y entre solicitudes, use HttpContext.Current.Session.
  • Para compartir datos dentro de una solicitud específica, use HttpContext.Current.Items.
  • Para compartir datos en toda la aplicación, escriba un mecanismo para eso o configure IIS para que trabaje con un solo proceso y escriba una aplicación singleton / use.

Por cierto, el número predeterminado de procesos de trabajo es 1, por eso la web está llena de gente pensando que los miembros estáticos tienen un scope de toda la aplicación.

Dado que los tipos están contenidos en un dominio de aplicación, esperaría que estuvieran presentes las clases estáticas siempre que el dominio de la aplicación no se recicla o si la solicitud recibe un dominio de aplicación diferente.

Puedo pensar en varias maneras de hacer que los objetos específicos para una solicitud particular dependan de lo que quieras hacer, por ejemplo, podrías instanciar el objeto en Application.BeginRequest y luego almacenarlo en el objeto HttpRequest para que todos los objetos en él puedan acceder. la tubería de procesamiento de solicitud.

Si no son exclusivos de cada solicitud, ¿hay alguna forma de permitir que lo estén?

Nop. Los miembros estáticos son propiedad del proceso ASP.NET y compartidos por todos los usuarios de la aplicación web. Tendrá que recurrir a otras técnicas de gestión de sesión, como las variables de sesión.

Normalmente, los métodos, propiedades y clases estáticos son comunes en el nivel de Application . Mientras la aplicación viva, se comparten.

Puede especificar un comportamiento diferente utilizando el atributo ThreadStatic . En ese caso, serán específicos del hilo actual, que creo que es específico para cada solicitud.
Sin embargo, no lo aconsejaría, ya que parece demasiado complicado.

Puede usar HttpContext.Current.Items para configurar cosas para una solicitud, o HttpContext.Current.Session para configurar cosas para un usuario (a través de las solicitudes).

Sin embargo, en general, a menos que tenga que usar cosas como Server.Transfer , la mejor forma es básicamente crear cosas una vez y luego pasarlas explícitamente a través de la invocación de métodos.