在下面的示例中,調(diào)用.Execute()ReactiveCommand 會掛起或創(chuàng)建死鎖。為什么會發(fā)生這種情況,避免這種情況的最佳方法是什么?該錯誤僅在調(diào)用 Dispatcher.CurrentDispatcher 時(shí)發(fā)生。不幸的是,不稱其為顯而易見的答案在更大的項(xiàng)目中不是一個選擇。我在項(xiàng)目中有nuget包reactiveui-core和reactiveui-winforms,都是v7.4.0。我正在使用 Resharper 從 Visual Studio 運(yùn)行 nunit 測試。該代碼是一個 NUnit 測試夾具,注意 TimeoutAfterAsync 是一個幫助方法,用于在一定超時(shí)后取消測試,在沒有這個包裝器的情況下觀察到行為[TestFixture]public class ReactiveCommandTests{ private static async Task<bool> ExecuteCommand() { await Task.Delay(1000); return true; } public static ReactiveCommand<Unit, bool> Command = ReactiveCommand.CreateFromTask(ExecuteCommand); public static ReactiveCommand<Unit, bool> CommandOnTaskpoolScheduler = ReactiveCommand.CreateFromTask(ExecuteCommand, outputScheduler: RxApp.TaskpoolScheduler); public static ReactiveCommand<Unit, bool> CommandAfterDispatcherInvoked = ReactiveCommand.CreateFromTask(ExecuteCommand); [Test, Order(1)] public async Task Test() { //THIS WORKS try { await TimeoutAfterAsync( Command.Execute(), TimeSpan.FromSeconds(5), "control"); } catch (TimeoutException) { Assert.Fail("Control case timed out (not expected)"); } } [Test, Order(2)] public async Task Test_CreateCommandAfterDispatcherCall() { //This line causes unwanted behaviour var x = Dispatcher.CurrentDispatcher; //THIS FAILS try { await TimeoutAfterAsync( CommandAfterDispatcherInvoked.Execute(), TimeSpan.FromSeconds(5), "after dispatcher creation"); } catch (TimeoutException) { Assert.Fail("Executing commandAfterDispatcherInvoked timed out (expected, but not understood"); } }
1 回答

慕田峪4524236
TA貢獻(xiàn)1875條經(jīng)驗(yàn) 獲得超5個贊
Dispatcher.CurrentDispatcher
很有趣;如果當(dāng)前線程還沒有調(diào)度器,它會為當(dāng)前線程創(chuàng)建一個調(diào)度器!這會導(dǎo)致單元測試出現(xiàn)問題,因?yàn)樾碌恼{(diào)度程序是為線程池線程創(chuàng)建的,該線程不是 STA 并且沒有消息泵。
理想的解決方案是不調(diào)用CurrentDispatcher
. 曾經(jīng)。使用await
orIProgress<T>
或(如果必須)SynchronizationContext
將結(jié)果/進(jìn)度/事件傳達(dá)給 UI 線程。這些抽象更容易為其創(chuàng)建測試環(huán)境。
但就目前而言,您可能可以使用WpfContext,這是 Async CTP 早期版本中包含的一種舊實(shí)用程序類型。WpfContext.Run
將接受一個委托,為當(dāng)前線程創(chuàng)建一個調(diào)度程序上下文,并在該調(diào)度程序上下文中執(zhí)行該委托,泵送其消息,直到異步操作完成。
- 1 回答
- 0 關(guān)注
- 106 瀏覽
添加回答
舉報(bào)
0/150
提交
取消