2010-02-15 8 views
5

el código:¿Por qué/cuándo las escrituras de sesión son vulnerables a la terminación de subprocesos?

Session["foo"] = "bar"; 
Response.Redirect("foo.aspx"); 

EL PROBLEMA:

Cuando foo.aspx lee "foo" de la sesión, que no está ahí. La sesión está allí, pero no hay ningún valor para "foo".

He observado esto de forma intermitente en nuestro entorno de producción. Pero no me refiero aquí para preguntar a question about Response.Redirect().

LA EXPLICACIÓN:

Bertrand Le Roy explica (la negrita es mía):

Ahora, lo redirección hace es enviar una cabecera especial al cliente para que se pide al servidor para una página diferente que la que estaba esperando. del lado del servidor, después de enviar este encabezado , redirigir finaliza la respuesta. Esto es algo muy violento. Response.End realmente detiene la ejecución de la página dondequiera que esté usando una ThreadAbortException. Lo que sucede realmente aquí es que el token de sesión se pierde en la batalla.

Mi conclusión es que Response.Redirect() puede ser pesado con los hilos finales. Y eso puede amenazar mis escrituras de sesión si ocurren demasiado cerca de esa mano dura.

LA PREGUNTA:

¿Qué pasa con ASP.NET gestión de sesiones hace que sea tan vulnerable a esto? La línea de código Response.Redirect() no comienza su ejecución hasta que la línea de escritura de la sesión está "terminada". ¿Cómo puede ser una amenaza para la escritura de mi sesión?

¿Qué ocurre con la escritura de la sesión que no "finaliza" antes de que se ejecute la siguiente línea de código? ¿Hay otros escenarios en los que las grabaciones de sesión se pierden de manera similar (como si nunca se hubieran producido)?

Respuesta

1

Después de probar varias alternativas (Response.Redirect (..., false), Server.Transfer(), y otras "soluciones" que ahora no puedo recordar), hemos encontrado una sola respuesta confiable a este problema .

Al mover nuestro estado de sesión de InProc a SqlServer, este comportamiento de nuestros sistemas fue erradicado de manera efectiva, dejando Response.Redirect (...) completamente confiable. Si otras pruebas muestran lo contrario, informaré aquí, pero digo, para que esto suceda en su entorno: mueva su estado de sesión a SqlServer (o está "fuera de InProc" lo suficientemente bueno? No estoy seguro).

2

No estoy lo suficientemente familiarizado con los aspectos internos de la escritura de la sesión, pero me imagino que tiene algunas complejidades, ya que se basa en traducir las cookies de la sesión del navegador en una identificación del servidor. Además, ThreadAbortExceptions do have special considerations en el tiempo de ejecución, que puede jugar aquí, no estoy seguro.

En cualquier caso, Response.Redirect() tiene una sobrecarga que toma un parámetro booleano que le permite especificar si desea finalizar el hilo o no.

Response.Redirect(string url, bool endResponse); 

Si llama con endResponse establecido en "falsa", será terminar con gracia, en lugar de llamar Thread.Abort() internamente. Sin embargo, esto significa que también ejecutará cualquier código que quede en el ciclo de vida de la página antes de finalizar.

Un buen compromiso es llamar al Response.Redirect(url, false) seguido de Application.CompleteRequest(). Esto permitirá que su redirección suceda, pero también cerrará con gracia el contexto de ejecución actual con una cantidad mínima de procesamiento de ciclo de vida adicional.

0

El reciclaje del grupo de aplicaciones puede hacer que su sesión desaparezca. Puede configurar el grupo de aplicaciones para que se recicle a horas fijas (recomendado, por la noche o durante períodos de poco uso) o aumente el período de tiempo de espera del reciclado de su grupo de aplicaciones.

Cuestiones relacionadas