Compartir a través de


Estado de la aplicación

Se puede compartir información en toda la aplicación mediante la clase HttpApplicationState, a la que normalmente se tiene acceso a través de la propiedad Application del objeto HttpContext. Esta clase expone un diccionario de objetos con valores y claves que se pueden utilizar para almacenar objetos de .NET Framework y valores escalares relacionados con varias solicitudes Web de varios clientes.

En este tema se proporciona información general acerca del estado de aplicación, se describe cómo utilizar el estado de aplicación, se presentan las colecciones de estados de aplicación y se trata la sincronización de estados de aplicación.

Información general sobre el estado de aplicación

Una aplicación ASP.NET es la suma de todos los archivos, páginas, controladores, módulos y código que residen en un directorio virtual dado y sus subdirectorios, y que los usuarios pueden solicitar a través de la jerarquía de directorios virtuales.

Por ejemplo, si desarrolla una aplicación que calcula los beneficios de una inversión en la intranet de su compañía, podría publicarla en un directorio virtual denominado /Inversión en un servidor Web. La estructura del directorio de tal aplicación podría tener una apariencia similar a la siguiente:

\Inversión

   \bin

   \image

   \xml

La primera vez que un cliente solicita un recurso URL desde el interior del espacio de nombres del directorio virtual de una determinada aplicación ASP.NET, se crea una instancia de la clase HttpApplicationState. Esto ocurre con cada aplicación Web almacenada en el equipo. El acceso a una de estas instancias creadas para cada aplicación es posible a través de una propiedad HttpContext denominada Application. Todos los HttpModules y HttpHandlers, por ejemplo una página ASP.NET, tienen acceso a una instancia del contexto y, por lo tanto, a la propiedad Application durante una determinada solicitud Web.

ASP.NET proporciona los siguientes elementos compatibles con el estado de aplicación:

  • Un servicio de estado fácil de utilizar que es compatible con versiones anteriores de ASP, funciona con todos los lenguajes admitidos por .NET y es coherente con otras API de .NET Framework.
  • Un diccionario de estados de aplicación a disposición de todos los controladores de solicitudes a los que se llame desde una aplicación. A diferencia de los Servicios de Internet Information Server (IIS) y de las versiones anteriores de ASP, en las que sólo las páginas pueden tener acceso a los estados de la aplicación, todas las instancias de IHttpHandler y IHttpModule pueden almacenar y recuperar variables globales dentro del diccionario.
  • Un mecanismo de sincronización sencillo e intuitivo que permite a los programadores coordinar fácilmente accesos simultáneos a variables almacenadas en el estado de aplicación.
  • Valores de estado de aplicación a los que se puede tener acceso sólo desde el código que se ejecuta en el contexto de la aplicación de origen. Otras aplicaciones que se ejecuten en el sistema no pueden tener acceso a los valores o modificarlos.

La forma más común de tener acceso al estado de aplicación es mediante la propiedad Application del objeto Page.

Utilizar el estado de aplicación

Las variables del estado de aplicación son, de hecho, variables globales para una aplicación ASP.NET dada. Al igual que los programadores de aplicaciones cliente, los programadores de ASP.NET siempre deben tener en cuenta el efecto que tiene almacenar un elemento como variable global.

Las cuestiones siguientes tienen una importancia especial en este contexto:

  • El efecto que tiene sobre la memoria almacenar un elemento en el estado de aplicación. La memoria que ocupan las variables almacenadas en el estado de aplicación no se liberan hasta que se elimina o se reemplaza el valor, a diferencia de una página Web individual, en la que todos los recursos dejan de utilizarse al concluir la solicitud Web. Guardar de manera definitiva en el estado de aplicación conjuntos de registros de 10 MB que se utilizan de vez en cuando, por ejemplo, no es la mejor forma de utilizar los recursos del sistema. En este ejemplo extremo, puede obtener mejores resultados si utiliza la clase Cache de ASP.NET.
  • Las implicaciones en cuanto a simultaneidad y sincronización derivadas de almacenar y obtener acceso a una variable global en un entorno de servidor multiproceso. Varios subprocesos de una aplicación pueden obtener acceso simultáneo a valores almacenados en el estado de aplicación. Debe asegurarse siempre de que si un objeto del ámbito de una aplicación es de subprocesamiento libre, contiene compatibilidad integrada con la sincronización. Todos los objetos personalizados orientados a Common Language Runtime son de subprocesamiento libre. Si un objeto del ámbito de una aplicación no es de subprocesamiento libre, debe asegurarse de que se codifiquen métodos explícitos de sincronización a ambos lados para evitar bloqueos irreversibles, condiciones de anticipación e infracciones de acceso.
  • Las implicaciones en cuanto a escalabilidad derivadas de almacenar y obtener acceso a una variable global dentro de un entorno de servidor multiproceso. Siempre que se intente escribir o actualizar un archivo, se deben utilizar bloqueos. Los bloqueos que protegen recursos globales son también globales y el código que se ejecuta en múltiples subprocesos que obtienen acceso a recursos globales termina eventualmente por competir en estos bloqueos. Como consecuencia, el sistema operativo bloquea los subprocesos de trabajo hasta que el bloqueo esté disponible. En entornos servidor de alta carga de trabajo, este bloqueo puede producir una grave hiperpaginación de subprocesos en el sistema. En sistemas con varios procesadores, puede dar lugar a la infrautilización del procesador (ya que en teoría se pueden paralizar todos los subprocesos de un procesador mientras se espera a que un bloqueo compartido esté disponible) y a una reducción considerable de la escalabilidad global.
  • Las implicaciones para el ciclo de vida derivadas de la información almacenada en el estado de aplicación. El dominio de aplicación de .NET Framework o el proceso que aloja una aplicación basada en .NET se pueden anular y destruir en cualquier momento de la ejecución de la aplicación (como resultado de bloqueos del equipo, actualizaciones de códigos, reinicios programados de procesos, etc.). Como los datos almacenados en el estado de aplicación no son perdurables, se pierden si se destruye el host que los contiene. Si desea que el estado sobreviva a este tipo de errores, debe almacenarlo en una base de datos o en cualquier otro tipo de almacén duradero.
  • El estado de la aplicación no se comparte en una matriz de servidores Web (en la que una aplicación se aloja en varios servidores) o en una matriz de procesos Web (en la que una aplicación se aloja en varios procesos del mismo servidor). Las variables almacenadas en el estado de aplicación en cualquiera de estos escenarios son globales sólo para el proceso específico en el que se ejecuta la aplicación. Cada proceso de aplicación puede tener valores distintos. Por lo tanto, no se puede confiar en el estado de aplicación para almacenar valores únicos o para actualizar contadores globales, por ejemplo, en un escenario de matriz de servidores Web o de matriz de procesos Web.

A pesar de estas cuestiones, las variables de nivel de aplicación bien diseñadas pueden ser muy eficaces en las aplicaciones Web. Puede hacer una sola (o poco frecuente) carga y cálculo de información y, después, utilizar el estado de aplicación para almacenarla en caché y así poder obtener rápidamente acceso a ella en la memoria durante las solicitudes Web posteriores.

Por ejemplo, un sitio Web bursátil podría obtener información exhaustiva sobre acciones (quizá 40 MB de datos) proveniente de una base de datos cada 5 minutos y, después, almacenarla en caché en el estado de aplicación, donde todas las solicitudes de búsqueda posteriores pueden obtener acceso a ella. Como resultado, el rendimiento de cada solicitud mejora notablemente, ya que las solicitudes entrantes no tienen que pasar de un proceso a otro, de un equipo a otro o de una base de datos a otra. Por otro lado, usando la caché se aprovecharían mejor los recursos para bloques de gran tamaño de datos transitorios.

Colecciones de estados de aplicación

La clase HttpApplicationState expone dos colecciones de estado: Contents y StaticObjects.

La colección Contents expone todos los elementos variables que se han agregado a la colección de estados de aplicación directamente mediante código. Por ejemplo:

'  Visual Basic code from within a page, a handler, or Global.asax.
Application("Message") = "MyMsg"
Application("AppStartTime") = Now
[C#]
// C# code from within a page, a handler, or Global.asax.
Application["Message"] = " MyMsg";
Application["AppStartTime"] = DateTime.Now;

En el caso de versiones anteriores de ASP, también se puede tener acceso a estas variables mediante la propiedad Contents del objeto de aplicación, como se indica en el ejemplo siguiente:

' Visual Basic code from within a page, a handler, or Global.asax.
Application.Contents("Message") = " MyMsg"
Application.Contents("AppStartTime") = Now
[C#]
// Visual Basic code from within a page, a handler, or Global.asax.
Application.Contents["Message"] = " MyMsg";
Application.Contents["AppStartTime"] = DateTime.Now;

La colección StaticObjects expone todos los elementos variables que se han agregado a la colección de estados de aplicación mediante etiquetas <object runat="server"> en el archivo Global.asax con un ámbito de aplicación. Por ejemplo:

' Global.asax definition.
<object runat="server" scope="application" ID="MyInfo" PROGID="MSWC.MYINFO">
</OBJECT>

No se pueden agregar objetos a la colección StaticObjects desde ningún otro sitio de una aplicación ASP.NET. La colección generará una excepción NotSupportedException si intenta agregar objetos directamente mediante código.

Tenga en cuenta que el compilador de páginas de .NET escribe automáticamente referencias a miembros en todos los objetos almacenados en la colección StaticObjects durante la compilación de páginas para que los programadores puedan tener acceso a esos objetos aplicación durante las solicitudes de páginas sin tener que hacer referencia a la colección Application. Por ejemplo:

<html>
   </body>
      Application Level Title: <%= MyInfo.Title %>
   <body>
</html>

Sincronización de estados de aplicación

Varios subprocesos de una aplicación pueden obtener simultáneamente acceso a valores almacenados en el estado de aplicación. Por lo tanto, cuando cree un elemento que necesite acceso a valores del estado de aplicación, deberá asegurarse de que el objeto del estado de aplicación es de subprocesamiento libre y realiza su propia sincronización interna o bien realiza una sincronización manual como protección frente a condiciones de anticipación, bloqueos irreversibles e infracciones de acceso.

La clase HttpApplicationState proporciona dos métodos, Lock y Unlock, que sólo permiten que un subproceso tenga acceso a la vez a variables del estado de aplicación.

Al llamar a Lock en el objeto Application, ASP.NET impide que el código que se ejecuta en otros subprocesos de trabajo tenga acceso a la información contenida en el estado de aplicación. Estos subprocesos se desbloquearán cuando el subproceso que llamó a Lock llame al correspondiente método Unlock del objeto Application.

En el siguiente ejemplo de código se muestra el uso de bloqueos como protección frente a condiciones de anticipación:

' Visual Basic code from within a page, a handler, or Global.asax.
Application.Lock()
Application("SomeGlobalCounter") = _
   CType(Application("SomeGlobalCounter"), Integer) + 1
Application.UnLock()
[C#]
// C# code from within a page, a handler, or Global.asax.
Application.Lock();
Application["SomeGlobalCounter"] =
   (int)Application["SomeGlobalCounter"] + 1;
Application.UnLock();

Si no llama explícitamente a Unlock, .NET Framework quita automáticamente el bloqueo cuando finaliza la solicitud, cuando se agota el tiempo de espera de la solicitud o cuando se produce un error no controlado durante la ejecución de la solicitud y ésta no se efectúa correctamente. Este desbloqueo automático impide que la aplicación se bloquee irreversiblemente.

Vea también

Administración de estados de ASP.NET | Aplicaciones ASP.NET