Решение Ритча Мелтона у меня не сработало.Это потому, что моя TestInitialize
функция асинхронная, как и мои тесты, поэтому с каждым await
текущий SynchronizationContext
теряется.Это потому, что, как указывает MSDN, класс SynchronizationContext
является «тупым» и просто помещает всю работу в очередь в пул потоков.
Для меня сработало просто пропустить вызов FromCurrentSynchronizationContext
, когда нетSynchronizationContext
(то есть, если текущий контекст ноль ).Если нет потока пользовательского интерфейса, мне не нужно синхронизироваться с ним.
TaskScheduler syncContextScheduler;
if (SynchronizationContext.Current != null)
{
syncContextScheduler = TaskScheduler.FromCurrentSynchronizationContext();
}
else
{
// If there is no SyncContext for this thread (e.g. we are in a unit test
// or console scenario instead of running in an app), then just use the
// default scheduler because there is no UI thread to sync with.
syncContextScheduler = TaskScheduler.Current;
}
Я нашел это решение более простым, чем альтернативы, где:
- Передайте
TaskScheduler
в ViewModel (через внедрение зависимостей) - Создайте тест
SynchronizationContext
и "фальшивый" поток пользовательского интерфейса для запуска тестов - для меня больше проблем, чем оно стоит
Я теряю некоторые нюансы потока, но я не проверяю явно, что мои обратные вызовы OnPropertyChanged срабатывают в определенном потоке, поэтому я согласен с этим.Другие ответы, использующие new SynchronizationContext()
, на самом деле не достигают большего успеха для этой цели.