En un sitio web ASP.NET, ¿las clases estáticas son exclusivas de cada solicitud web, o se crean instancias cuando es necesario y se GCed cuando 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 esperaba. Hubiera esperado que las clases estáticas fueran únicas para cada solicitud, pero no parece que ese sea el caso.
Si no son exclusivos de cada solicitud, ¿hay alguna forma de permitir que lo sean?
ACTUALIZACIÓN:
La respuesta que me dieron driis fue exactamente lo que necesitaba. Ya estaba usando una clase singleton, sin embargo, estaba usando una instancia estática y, por lo tanto, se compartía entre solicitudes incluso si los usuarios eran diferentes, lo que en este caso era algo malo. El uso HttpContext.Current.Items
resuelve mi problema perfectamente. Para cualquiera que se encuentre con esta pregunta en el futuro, aquí está mi implementación, simplificada y acortada para que sea fácil de 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;
}
}
}
filterContext.Result = new RedirectResult(...)
perderá sus artículos porque se creará un nuevo HttpContext. Más detalles aquí: stackoverflow.com/questions/16697601/…Respuestas:
Sus clases estáticas y los campos de instancia estática se comparten entre todas las solicitudes a la aplicación y tienen el mismo tiempo de vida 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 serán GC 'antes de que el grupo de aplicaciones sea reciclado, y por lo tanto, todo lo que hace referencia la instancia estática no será GC'ed. Esto puede conducir a problemas de uso de memoria.
Si necesita una instancia con el mismo tiempo de vida que una solicitud, sugeriría usar la
HttpContext.Current.Items
colección. Esto es, por diseño, un lugar para almacenar cosas que necesita durante 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 enHttpContext.Current.Items
. (En mi biblioteca común para ASP.NET, tengo una clase SingletonRequest genérica para este propósito).fuente
HttpContext.Current.Items
?"static instances will not be GC'ed before the application pool is recycled, and therefore everything that is referenced by the static instance, will not be GC'ed"
- ¿Hay alguna fuente para esto, porque no tiene ningún sentido y entra en conflicto con lo que he leído en otras partes? Cuando el AppPool se recicla, el dominio de la aplicación relacionado se derriba por completo y GC'd. Cuando esto sucede, las instancias estáticas relacionadas también serán GC'd porque su raíz (el AppDomain) se ha ido. Como parte del grupo de reciclaje, se crea un nuevo AppDomain y se inicializan sus instancias estáticas asociadas.Los miembros estáticos solo tienen un alcance 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.
Por cierto, el número predeterminado de procesos de trabajo es 1, por eso la web está llena de personas que piensan que los miembros estáticos tienen un alcance de toda la aplicación.
fuente
Dado que los tipos están contenidos en un dominio de aplicación, esperaría que las clases estáticas estén presentes siempre que el dominio de la aplicación no se recicle, o si la solicitud es atendida por un dominio de aplicación diferente.
Se me ocurren varias formas de hacer que los objetos específicos de una solicitud en particular dependan de lo que desee hacer, por ejemplo, podría crear una instancia del objeto en Application.BeginRequest y luego almacenarlo en el objeto HttpRequest para que todos los objetos puedan acceder a él. la tubería de procesamiento de solicitudes.
fuente
No Los miembros estáticos son propiedad del proceso ASP.NET y todos los usuarios de la aplicación web los comparten . Deberá recurrir a otras técnicas de administración de sesión, como las variables de sesión.
fuente
Normalmente, los métodos estáticos, las propiedades y las clases son comunes en el
Application
nivel. Mientras viva la aplicación, se comparten.Puede especificar un comportamiento diferente utilizando el
ThreadStatic
atributo En ese caso, serán específicos para el hilo actual, que, creo, es específico para cada solicitud.Sin embargo, no recomendaría esto, ya que parece demasiado complicado.
Puede usarlo
HttpContext.Current.Items
para configurar cosas para una solicitud, oHttpContext.Current.Session
para configurar cosas para un usuario (a través de solicitudes).Sin embargo, en general, a menos que tenga que usar cosas como
Server.Transfer
, la mejor manera es básicamente crear cosas una vez y luego pasarlas explícitamente mediante la invocación de métodos.fuente