Marshall-By-Bleed explained

El otro día, mi compañero Pablo Doval puso un excelente post sobre una detección de bloqueos, más bien de interbloqueos, dentro de una aplicación en producción. De entre las muchas buenas prácticas y malas opciones a la hora de hacer sync locks dentro de las aplicaciones que comentó hubo una que por desconocida creo que merece la pena anotarla con este otro post. Pablo hizo referencia hacia un tema poco documentado en el Framework de .NET que es Marshall-By-Bleed según el cual es posible que dos dominios de aplicación distintos tengan un referencia al mismo objeto en memoria, si ya sé lo que todos hemos oído acerca del aislamiento por AppDomains, pero aún así es cierto con unas determinadas restricciones, la primera, y más restrictiva de todas, es que los tipos que disfrutan de Marshall-By-Bleed son solamente los tipos definidos en un dominio neutral como mscorlib.dll como por ejemplo Type y todos los tipos de reflexión al estilo XXXInfo. Según esto, a mayores de la mala práctica en cuanto a orientación a objetos de hacer un lock sobre typeof, podríamos tener interbloqueos realmente difíciles de detectar, si no está depurando Pablo Doval claro J ….. Los que me conocéis sabéis que siempre tiro al código para intentar explicar las cosas y esta vez no iba a ser menos por lo que aquí tenéis un pequeño tip explicativo J

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading;

 

 

namespace MarshallByBleed

{

class Program

{

static void Main(string[] args)

{

AutoResetEvent waitHandle = new AutoResetEvent(false);

 

lock (typeof(Program)) //cambiar a typeof(Object) para Marshall-By-Bleed

{

        AppDomain otherDomain = AppDomain.CreateDomain(“DOMAIN_B”);

        //DoCallback permite ejecutar código en

        // el ambiente de otro AppDomain

        otherDomain.DoCallBack(() =>

        ThreadPool.QueueUserWorkItem(state =>

        {

            lock (typeof(Program))//cambiar a typeof(Object) para Marshall-By-Bleed

            {

                Console.WriteLine(“No hay Marshall-By-Bleed”);

            }

        }, null)

    );

     waitHandle.WaitOne();

    }

    Console.ReadLine();

}

}

}

 

Os propongo que utilicéis el atributo LoaderOptimization para simular la carga de un dominio neutral y comprobéis como typeof(Program) también podría participar como Marshall-By-Bleed…

Saludos

Unai