How do I ensure view models are properly disposed of if they reference unmanaged resources or have event handlers such as handling elapsed on a dispatcher timer. In the first case, a finaliser is an option, although not ideal, but in the latter, it will never be called. How can we tell when there is no longer a view attached to the view model.
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
回答1:
I accomplished this by doing the following:
- Removing the StartupUri property from App.xaml.
Defining my App class as follows:
public partial class App : Application { public App() { IDisposable disposableViewModel = null; //Create and show window while storing datacontext this.Startup += (sender, args) => { MainWindow = new MainWindow(); disposableViewModel = MainWindow.DataContext as IDisposable; MainWindow.Show(); }; //Dispose on unhandled exception this.DispatcherUnhandledException += (sender, args) => { if (disposableViewModel != null) disposableViewModel.Dispose(); }; //Dispose on exit this.Exit += (sender, args) => { if (disposableViewModel != null) disposableViewModel.Dispose(); }; } }
回答2:
One possible, although not perfect solution:
Implement IDisposable on the View Model, then use this extension method in the constructor of the view.
public static void HandleDisposableViewModel(this FrameworkElement Element)
{
Action Dispose = () =>
{
var DataContext = Element.DataContext as IDisposable;
if (DataContext != null)
{
DataContext.Dispose();
}
};
Element.Unloaded += (s, ea) => Dispose();
Element.Dispatcher.ShutdownStarted += (s, ea) => Dispose();
}