调试内存泄漏,我注意到Messenger正在抓住一些处理过的对象。进一步调查,我发现如果从Task.Run中调用Register
,Messenger.Cleanup
将永远不会通过RequestCleanup
运行。
当注册和取消注册时,调用RequestCleanup
,将对Cleanup的调用添加到当前线程的Dispatcher,并将_isCleanupRegistered
设置为true
。问题是,此处通过Dispatcher.CurrentDispatcher
创建的调度程序从不运行Cleanup
,而_isCleanupRegistered
永远不会重新设置为false
。对RequestCleanup
的后续调用永远不会通过_isCleanupRequested
的检查。
public void RequestCleanup()
{
if (!_isCleanupRegistered)
{
Action cleanupAction = Cleanup;
//...other code
Dispatcher.CurrentDispatcher.BeginInvoke(
cleanupAction,
DispatcherPriority.ApplicationIdle,
null);
_isCleanupRegistered = true;
}
}
如果我将Dispatcher.CurrentDispatcher
更改为Application.Current.Dispatcher
,Cleanup
会按预期运行。注册和取消注册的正确方法是什么,以便清理逻辑按预期工作?
请注意,这是MVVM Light的 WPF 4.5 版本。