我正在尝试测试使用CommandManager.RequerySuggested
的类,并注意到调用CommandManager.InvalidateRequerySuggested
不会从我的测试中激活RequerySuggested
。这有什么原因以及如何解决这个问题? CommandManager
是否需要初始化?
重现问题的代码:
[Test]
public void InvalidateRequerySuggested_TriggersRequerySuggested()
{
bool triggered = false;
CommandManager.RequerySuggested += (s, a) => triggered = true;
CommandManager.InvalidateRequerySuggested();
Thread.Sleep(1000); // Just to be sure
Assert.True(triggered); // Never true
}
答案 0 :(得分:3)
正如msdn here所述,CommandManager.RequerySuggested
仅包含一个弱事件引用。在你的单元测试中,lambda表达式被垃圾收集。
尝试以下方法:
bool triggered;
EventHandler handler = (s, e) => triggered = true;
CommandManager.RequerySuggested += handler;
CommandManager.InvalidateRequerySuggested();
GC.KeepAlive(handler);
Assert.IsTrue(triggered);
<强>更新强>
通过进一步的调查,我相信我已经找到了问题。
CommandManager.InvalidateRequestSuggested()
使用当前的调度程序异步引发事件。
这是一个解决方案:
bool triggered;
EventHandler handler = (s, e) => triggered = true;
CommandManager.RequerySuggested += handler;
CommandManager.InvalidateRequerySuggested();
// Ensure the invalidate is processed
Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Background, new Action(() => { }));
GC.KeepAlive(handler);
Assert.IsTrue(triggered);
答案 1 :(得分:1)
此行为的另一个可能原因:我发现我们需要使用与调用RequerySuggested
的调度程序相同的调度程序订阅InvalidateRequerySuggested
事件。
我在订阅此事件的非UI线程上创建了一些对象,但事件没有被引发。改变
CommandManager.RequerySuggested += HandleRequerySuggestedSuggested;
到
Application.Current.Dispatcher.Invoke((Action)(() =>
CommandManager.RequerySuggested += HandleRequerySuggestedSuggested));
为我解决了。
答案 2 :(得分:0)
只需对您的事件处理程序进行强有力的引用