Muy bajo rendimiento de la tarea asíncrona ejecutada en threadpool en .Net nativo

He observado una extraña diferencia en el código nativo administrado vs .Net. Tengo un trabajo pesado redirigido a threadpool. Cuando ejecuto la aplicación en código administrado, todo funciona sin problemas, pero tan pronto como enciendo la compilación nativa, la tarea se ejecuta algunas veces más lento y tan lento que cuelga el hilo de la interfaz de usuario (supongo que la CPU está tan sobrecargada).

Aquí hay dos capturas de pantalla de la salida de depuración, la de la izquierda es del código administrado y la de la derecha es de la compilación nativa. Como puede ver, el tiempo consumido por la tarea de IU es casi el mismo en ambos casos, hasta el momento en que se inicia el trabajo de agrupación de subprocesos; luego, en la versión administrada, el tiempo transcurrido de la IU aumenta (de hecho, la IU se bloquea y no puede realizar ninguna acción). Los tiempos del trabajo de threadpool hablan por sí mismos.

El código de muestra para reproducir el problema:

private int max = 2000;
private async void UIJob_Click(object sender, RoutedEventArgs e)
{
    IProgress<int> progress = new Progress<int>((p) => { MyProgressBar.Value = (double)p / max; });
    await Task.Run(async () => { await SomeUIJob(progress); });
}

private async Task SomeUIJob(IProgress<int> progress)
{
    Stopwatch watch = new Stopwatch();
    watch.Start();
    for (int i = 0; i < max; i++)
    {
        if (i % 100 == 0) { Debug.WriteLine($"     UI time elapsed => {watch.ElapsedMilliseconds}"); watch.Restart(); }
        await Task.Delay(1);
        progress.Report(i);
    }
}

private async void ThreadpoolJob_Click(object sender, RoutedEventArgs e)
{
    Debug.WriteLine("Firing on Threadpool");
    await Task.Run(() =>
   {
       double a = 0.314;
       Stopwatch watch = new Stopwatch();
       watch.Start();
       for (int i = 0; i < 50000000; i++)
       {
           a = Math.Sqrt(a) + Math.Sqrt(a + 1) + i;
           if (i % 10000000 == 0) { Debug.WriteLine($"Threadpool -> a value = {a} got in {watch.ElapsedMilliseconds} ms"); watch.Restart(); };
       }
   });
    Debug.WriteLine("Finished with Threadpool");
}

Si necesita una muestra completa, entonces puededescarguelo aqui.

Como he probado, la diferencia aparece tanto en el código optimizado / no optimizado, tanto en las versiones de depuración como de lanzamiento.

¿Alguien tiene una idea de qué puede causar el problema?

Respuestas a la pregunta(1)

Su respuesta a la pregunta