Son instancias de clase estáticas únicas para una solicitud o un servidor en ASP.NET?


En un ASP.NET sitio web, ¿son las clases estáticas únicas para cada solicitud web, o se instancian cuando es necesario y GCed cuando el GC decide deshacerse de ellos?

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 ese sea el caso.

Si no son únicos para cada solicitud, hay una manera de ¿permitir que lo sean?

ACTUALIZACIÓN:
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, se estaba compartiendo 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 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;
        }
    }
}
Author: Dan Herbert, 2008-10-12

5 answers

Las clases estáticas y los campos de instancia estáticos 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 serán GC'ed antes de que se recicle el grupo de aplicaciones, y por lo tanto todo lo que es referenciado por la instancia estática, no será GC'ed. Esto puede llevar al uso de memoria problema.

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 usted necesita througout 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).

 128
Author: driis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-25 19:18:41

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

  • Para compartir datos con un usuario específico y entre solicitudes, use HttpContext.Actual.Sesion.
  • Para compartir datos dentro de una solicitud específica, utilice HttpContext.Actual.Elemento.
  • Para compartir datos en toda la aplicación, escriba un mecanismo para ello, o configure IIS para que funcione con un solo proceso y escriba una aplicación singleton / use.

Por cierto, el número predeterminado de procesos de trabajo es 1, por lo que esta es la razón por la que la web está llena de personas que piensan que los miembros estáticos tienen un alcance de toda la aplicación.

 20
Author: Moshe Bixenshpaner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-20 12:14:28

Dado que los tipos están contenidos en un dominio de aplicación, esperaría que las clases estáticas estén presentes siempre y cuando el dominio de aplicación no se recicle, o si la solicitud es servida 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 quiera hacer, por ejemplo, podría instanciar el objeto en la Aplicación.BeginRequest y luego almacenarlo en el objeto HttpRequest para que todos los objetos del procesamiento de solicitudes puedan acceder a él gasoducto.

 11
Author: Sijin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-12 02:30:05

Si no son únicos para cada solicitud, ¿hay alguna manera de permitir que lo sean?

No. Static members are owned by the ASP.NET proceso y compartido por todos los usuarios de la aplicación Web. Tendrá que recurrir a otras técnicas de administración de sesiones, como las variables de sesión.

 4
Author: rp.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-12 02:57:37

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

Puede especificar un comportamiento diferente utilizando el atributo ThreadStatic. En ese caso, serán específicos para el hilo actual, que, creo, es específico para cada solicitud.
Sin embargo, no aconsejaría esto, 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 peticiones).

En general, sin embargo, 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 a través de la invocación del método.

 0
Author: Sklivvz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-12 10:02:21