Estou usando o Tasks para executar chamadas de servidor de longa duração em meu ViewModel e os resultados são encaminhados de volta ao Dispatcher
uso TaskScheduler.FromSyncronizationContext()
. Por exemplo:
var context = TaskScheduler.FromCurrentSynchronizationContext();
this.Message = "Loading...";
Task task = Task.Factory.StartNew(() => { ... })
.ContinueWith(x => this.Message = "Completed"
, context);
Isso funciona bem quando executo o aplicativo. Mas quando eu executo meus NUnit
testes em Resharper
, recebo a mensagem de erro na chamada para FromCurrentSynchronizationContext
as:
O SynchronizationContext atual não pode ser usado como TaskScheduler.
Acho que isso ocorre porque os testes são executados em threads de trabalho. Como posso garantir que os testes sejam executados no thread principal? Quaisquer outras sugestões são bem-vindas.
TaskScheduler.FromCurrentSynchronizationContext()
dentro de um lambda e a execução foi adiada para outro thread. obter o contexto fora de lambda corrigiu o problema.Respostas:
Você precisa fornecer um SynchronizationContext. É assim que eu lido com isso:
fonte
TestInitializeAttribute
, caso contrário, só passa o primeiro teste.A solução de Ritch Melton não funcionou para mim. Isso ocorre porque minha
TestInitialize
função é assíncrona, assim como meus testes, portanto, a cada momentoawait
a correnteSynchronizationContext
é perdida. Isso ocorre porque, como aponta o MSDN, aSynchronizationContext
classe é "burra" e apenas enfileira todo o trabalho para o pool de threads.O que funcionou para mim foi simplesmente ignorar a
FromCurrentSynchronizationContext
chamada quando não havia umSynchronizationContext
(isto é, se o contexto atual for nulo ). Se não houver UI thread, não preciso sincronizar com ele em primeiro lugar.Achei essa solução mais direta do que as alternativas, que eram:
TaskScheduler
para o ViewModel (via injeção de dependência)SynchronizationContext
e um thread de IU "falso" para os testes serem executados - muito mais problemas para mim que vale a penaPerco algumas nuances de threading, mas não estou testando explicitamente se meus retornos de chamada OnPropertyChanged são acionados em um thread específico, portanto, estou bem com isso. As outras respostas usando
new SynchronizationContext()
realmente não fazem nada melhor para esse objetivo de qualquer maneira.fonte
else
caso irá falhar também em um aplicativo de serviço do Windows, resultandosyncContextScheduler == null
[RequiresThread]
atributo.Combinei várias soluções para ter garantia de funcionamento do SynchronizationContext:
Uso:
fonte