Dispatcher.Invoke() 在 NUnit 测试中抛出 TaskCanceledException
Dispatcher.Invoke() throws TaskCanceledException in NUnit Tests
我正在尝试使用接口从我们的视图模型中抽象出 Dispatcher
。我创建了该接口的模拟实现,如下所示:
public class MockIDispatcher : IDispatcher, IDisposable
{
public MockIDispatcher()
{
var dispatcherThread = new Thread(Dispatcher.Run) { IsBackground = true };
dispatcherThread.SetApartmentState(ApartmentState.STA);
dispatcherThread.Start();
while ((Dispatcher = Dispatcher.FromThread(dispatcherThread)) == null) Thread.Yield(); // need to wait until the thread we created has started its dispatcher
}
internal Dispatcher Dispatcher { get; }
/* ... more implementation here */
}
我创建了一个虚拟 NUnit 测试,如下所示,但是对 Dispatcher.Invoke()
的调用抛出了 TaskCanceledException
.
[Test]
public void TestPoc()
{
var foo = new MockIDispatcher();
foo.Dispatcher.Invoke(() =>
{
Debug.WriteLine("Hey there!");
});
}
关于如何让这段代码正常工作有什么建议吗?我想在幕后实际使用 Dispatcher,以便更轻松地玩 SynchronizationContext
s 之类的东西。
问题似乎与我如何在构造函数中获得 Dispatcher
有关。我如下所示更改了构造函数,这解决了问题。看起来您可能需要先在线程上实际调用 Dispatcher.CurrentDispatcher
。调用 Dispatcher.Run()
是不够的。
public MockIDispatcher()
{
using (var mre = new ManualResetEvent(false))
{
Dispatcher dispatcher = null;
var dispatcherThread = new Thread(() =>
{
dispatcher = Dispatcher.CurrentDispatcher;
// ReSharper disable once AccessToDisposedClosure Not Possible because we are waiting inside the using loop
mre.Set();
try { Dispatcher.Run(); } catch { /* swallow exceptions */ }
}) { IsBackground = true };
dispatcherThread.SetApartmentState(ApartmentState.STA);
dispatcherThread.Start();
mre.WaitOne();
Dispatcher = dispatcher;
}
}
我正在尝试使用接口从我们的视图模型中抽象出 Dispatcher
。我创建了该接口的模拟实现,如下所示:
public class MockIDispatcher : IDispatcher, IDisposable
{
public MockIDispatcher()
{
var dispatcherThread = new Thread(Dispatcher.Run) { IsBackground = true };
dispatcherThread.SetApartmentState(ApartmentState.STA);
dispatcherThread.Start();
while ((Dispatcher = Dispatcher.FromThread(dispatcherThread)) == null) Thread.Yield(); // need to wait until the thread we created has started its dispatcher
}
internal Dispatcher Dispatcher { get; }
/* ... more implementation here */
}
我创建了一个虚拟 NUnit 测试,如下所示,但是对 Dispatcher.Invoke()
的调用抛出了 TaskCanceledException
.
[Test]
public void TestPoc()
{
var foo = new MockIDispatcher();
foo.Dispatcher.Invoke(() =>
{
Debug.WriteLine("Hey there!");
});
}
关于如何让这段代码正常工作有什么建议吗?我想在幕后实际使用 Dispatcher,以便更轻松地玩 SynchronizationContext
s 之类的东西。
问题似乎与我如何在构造函数中获得 Dispatcher
有关。我如下所示更改了构造函数,这解决了问题。看起来您可能需要先在线程上实际调用 Dispatcher.CurrentDispatcher
。调用 Dispatcher.Run()
是不够的。
public MockIDispatcher()
{
using (var mre = new ManualResetEvent(false))
{
Dispatcher dispatcher = null;
var dispatcherThread = new Thread(() =>
{
dispatcher = Dispatcher.CurrentDispatcher;
// ReSharper disable once AccessToDisposedClosure Not Possible because we are waiting inside the using loop
mre.Set();
try { Dispatcher.Run(); } catch { /* swallow exceptions */ }
}) { IsBackground = true };
dispatcherThread.SetApartmentState(ApartmentState.STA);
dispatcherThread.Start();
mre.WaitOne();
Dispatcher = dispatcher;
}
}