SynchronizationContext не передается при использовании await

Мы планируем использовать async / await в наших моделях представления MVVM, но столкнулись с серьезной проблемой при модульном тестировании этого кода. При использовании NUnit и написанного от руки макета для наших сообщений мы теряем текущийSynchronizationContext.

Лучше всего показывать следующий небольшой пример кода:

[Test] public void TestMethod()
{       
  Func<Task> asyncMethod = async () =>
    {
      var context = SynchronizationContext.Current;
      await TaskEx.Yield();
      Assert.AreEqual(context, SynchronizationContext.Current);
    };

    // Establish the new context
    var syncCtx = new SingleThreadSynchronizationContext(false);
    SynchronizationContext.SetSynchronizationContext(syncCtx);

    // Invoke the function and alert the context to when it completes
    var t = asyncMethod();
    t.ContinueWith(delegate { syncCtx.Complete(); }, TaskScheduler.Default);

    // Pump continuations and propagate any exceptions
    syncCtx.RunOnCurrentThread();
    t.GetAwaiter().GetResult();
}

На самом деле большая часть этого кода украдена из реализации AsyncPump от Стивена Таубав своем блоге.

Интересное все, что нужно для прохождения этого теста, бросается вExecutionContext.SuppressFlow(); перед вызовом асинхронного метода. Этого может быть достаточно, чтобы решить нашу проблему, но я недостаточно знаю о ExecutionContext, и я хочу немного глубже понять, что происходит.

Почему код, сгенерированный оператором await, поглощает текущий SynchronizationContext?
Есть ли другой очевидный способ использования однопоточного контекста для модульного тестирования асинхронного / ожидающего кода?

PS: мы используем .Net4 и Microsoft.CompilerServices.AsyncTargetingPack.Net4

PPS: это также происходит в простом проекте с использованием стабильного Microsoft.Bcl.Async вместо ATP

Ответы на вопрос(2)

Ваш ответ на вопрос