CommandManager.InvalidateRequerySuggested不会激发RequerySuggeste
本文关键字:RequerySuggeste InvalidateRequerySuggested CommandManager | 更新日期: 2023-09-27 18:19:42
我试图测试一个使用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
}
如msdn中备注下所述,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);
InvalidateRequerySuggested
相同的Dispatcher来订阅RequerySuggested
事件
我在订阅了此事件的非UI线程上创建了一些对象,但该事件没有引发。更改
CommandManager.RequerySuggested += HandleRequerySuggestedSuggested;
至
Application.Current.Dispatcher.Invoke((Action)(() =>
CommandManager.RequerySuggested += HandleRequerySuggestedSuggested));
为我解决了这个问题。
只需保留对事件处理程序的强引用