Como proteger pools de aplicativos de exceções de serialização de sessão?

Estamos usando um provedor de sessões fora de processo (Dimensionar) para um aplicativo ASP.NET e percebemos quequando um objeto que não está configurado corretamente para desserialização entra inadvertidamente na sessãoeventualmente, fazer com que todo o processo seja encerrado.

A reprodução e o manuseio desse cenário é onde fica ainda mais interessante.

A exceção que encerra o processo é levantada emAnyStaObjectsInSessionState cuja implementação é bastante direta:

internal static bool AnyStaObjectsInSessionState(HttpSessionState session)
{
    if (session != null)
    {
        int count = session.Count;
        for (int i = 0; i < count; i++)
        {
            object obj2 = session[i];
            if (((obj2 != null) && (obj2.GetType().FullName == "System.__ComObject"))
                && (UnsafeNativeMethods.AspCompatIsApartmentComponent(obj2) != 0))
            {
                return true;
            }
        }
    }
    return false;
}

Aqui está o rastreamento de pilha que mostra como as exceções aqui encerram o processo:

An unhandled exception occurred and the process was terminated.

Application ID: /LM/W3SVC/1/ROOT

Process ID: 4208

Exception: System.Runtime.Serialization.SerializationException

Message: The constructor to deserialize an object of type 'Lucene.Net.QueryParsers.ParseException' was not found.

StackTrace:    at System.Runtime.Serialization.ObjectManager.CompleteISerializableObject(Object obj, SerializationInfo info, StreamingContext context)
   at System.Runtime.Serialization.ObjectManager.FixupSpecialObject(ObjectHolder holder)
   at System.Runtime.Serialization.ObjectManager.DoFixups()
   at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
   at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
   at System.Web.Util.AltSerialization.ReadValueFromStream(BinaryReader reader)
   at System.Web.SessionState.SessionStateItemCollection.ReadValueFromStreamWithAssert()
   at System.Web.SessionState.SessionStateItemCollection.DeserializeItem(String name, Boolean check)
   at System.Web.SessionState.SessionStateItemCollection.DeserializeItem(Int32 index)
   at System.Web.SessionState.SessionStateItemCollection.get_Item(Int32 index)
   at System.Web.SessionState.HttpSessionStateContainer.get_Item(Int32 index)
   at System.Web.Util.AspCompatApplicationStep.AnyStaObjectsInSessionState(HttpSessionState session)
   at System.Web.HttpApplicationFactory.FireSessionOnEnd(HttpSessionState session, Object eventSource, EventArgs eventArgs)
   at System.Web.SessionState.SessionOnEndTargetWorkItem.RaiseOnEndCallback()
   at System.Web.Util.WorkItem.CallCallbackWithAssert(WorkItemCallback callback)
   at System.Threading.ExecutionContext.runTryCode(Object userData)
   at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading._ThreadPoolWaitCallback.PerformWaitCallbackInternal(_ThreadPoolWaitCallback tpWaitCallBack)
   at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback(Object state)

InnerException: System.Runtime.Serialization.SerializationException

Message: The constructor to deserialize an object of type 'Lucene.Net.QueryParsers.ParseException' was not found.

StackTrace:    at System.Runtime.Serialization.ObjectManager.GetConstructor(Type t, Type[] ctorParams)
   at System.Runtime.Serialization.ObjectManager.CompleteISerializableObject(Object obj, SerializationInfo info, StreamingContext context)

Gostaríamos de entender duas coisas:

Quando fazFireSessionOnEnd acionar um fornecedor fora de processo e, mais importante, como podemos imitar isso em um ambiente de desenvolvimento que não está sob carga? Eu experimentei tempos limite de sessão reduzidos (definido para um minuto), invocando manualmente Abandon () e manualmente GC.Collect (), tudo sem sucesso.

Podemos capturar erros que ocorrem nesta etapa para proteger o pool de aplicativos? As exceções levantadas aqui são registradas comOrigem = ASP.NET 2.0.50727.0 e não alcance os manipuladores de erro do aplicativo em global.asax. O que podemos fazer para nos proteger desse cenário, mesmo após a aplicação de verificações e balanços apropriados nos objetos vinculados à sessão?

Quaisquer ideias serão apreciadas.

questionAnswers(3)

yourAnswerToTheQuestion