ani*_*vas 96 c# multithreading nunit task-parallel-library resharper-6.0
我正在使用Tasks在我的ViewModel中运行长时间运行的服务器调用,结果将被重新编组Dispatcher使用TaskScheduler.FromSyncronizationContext().例如:
var context = TaskScheduler.FromCurrentSynchronizationContext();
this.Message = "Loading...";
Task task = Task.Factory.StartNew(() => { ... })
.ContinueWith(x => this.Message = "Completed"
, context);
Run Code Online (Sandbox Code Playgroud)
这在我执行应用程序时工作正常.但是当我运行我的NUnit测试时,Resharper我在调用时收到错误消息FromCurrentSynchronizationContext:
当前的SynchronizationContext可能不会用作TaskScheduler.
我想这是因为测试是在工作线程上运行的.如何确保测试在主线程上运行?欢迎任何其他建议.
Rit*_*ton 139
您需要提供SynchronizationContext.这就是我处理它的方式:
[SetUp]
public void TestSetUp()
{
SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
}
Run Code Online (Sandbox Code Playgroud)
Sap*_*pph 21
Ritch Melton的解决方案对我不起作用.这是因为我的TestInitialize函数是异步的,就像我的测试一样,因此每await一个电流SynchronizationContext都会丢失.这是因为MSDN指出,SynchronizationContext该类是"哑",只是将所有工作排队到线程池.
对我来说有用的实际上就是在FromCurrentSynchronizationContext没有a时跳过调用SynchronizationContext(也就是说,如果当前上下文为null).如果没有UI线程,我首先不需要与它同步.
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;
}
Run Code Online (Sandbox Code Playgroud)
我发现这个解决方案比替代方案更直接,其中:
TaskScheduler给ViewModel(通过依赖注入)SynchronizationContext和一个"虚假的"UI线程,让测试运行起来 - 这对我来说更麻烦,值得我失去了一些线程细微差别,但我没有明确测试我的OnPropertyChanged回调在特定线程上触发,所以我没关系.new SynchronizationContext()无论如何,使用其他答案对于该目标并没有做得更好.