Limpiar CallContext en TPL

Dependiendo de si estoy usando un código basado en async / await o TPL, obtengo dos comportamientos diferentes con respecto a la limpieza de lógicaCallContext.

Puedo establecer y borrar lógicoCallContext exactamente como espero si uso el siguiente código asíncrono / espera:

class Program
{
    static async Task DoSomething()
    {
        CallContext.LogicalSetData("hello", "world");

        await Task.Run(() =>
            Debug.WriteLine(new
            {
                Place = "Task.Run",
                Id = Thread.CurrentThread.ManagedThreadId,
                Msg = CallContext.LogicalGetData("hello")
            }))
            .ContinueWith((t) =>
                CallContext.FreeNamedDataSlot("hello")
                );

        return;
    }

    static void Main(string[] args)
    {
        DoSomething().Wait();

        Debug.WriteLine(new
        {
            Place = "Main",
            Id = Thread.CurrentThread.ManagedThreadId,
            Msg = CallContext.LogicalGetData("hello")
        });

    }
}

Lo anterior genera lo siguiente:

{Place = Task.Run, Id = 9, Msg = world}
{Lugar = Principal, Id = 8, Mensaje =}

Observe laMsg = lo que indica queCallContext en el hilo principal se ha liberado y está vacío.

Pero cuando cambio al código TPL / TAP puro no puedo lograr el mismo efecto ...

class Program
{
    static Task DoSomething()
    {
        CallContext.LogicalSetData("hello", "world");

        var result = Task.Run(() =>
            Debug.WriteLine(new
            {
                Place = "Task.Run",
                Id = Thread.CurrentThread.ManagedThreadId,
                Msg = CallContext.LogicalGetData("hello")
            }))
            .ContinueWith((t) =>
                CallContext.FreeNamedDataSlot("hello")
                );

        return result;
    }

    static void Main(string[] args)
    {
        DoSomething().Wait();

        Debug.WriteLine(new
        {
            Place = "Main",
            Id = Thread.CurrentThread.ManagedThreadId,
            Msg = CallContext.LogicalGetData("hello")
        });
    }
}

Lo anterior genera lo siguiente:

{Place = Task.Run, Id = 10, Msg = world}
{Lugar = Principal, Id = 9, Mensaje = mundo}

¿Hay algo que pueda hacer para obligar a TPL a "liberar" lo lógico?CallContext de la misma manera que lo hace el código asíncrono / espera?

No estoy interesado en alternativas aCallContext.

Espero arreglar el código TPL / TAP anterior para poder usarlo en proyectos dirigidos al marco .net 4.0. Si eso no es posible en .net 4.0, todavía tengo curiosidad por saber si se puede hacer en .net 4.5.

Respuestas a la pregunta(2)

Su respuesta a la pregunta