在MVVM中使用dispose取消订阅事件
在MVVM中使用dispose取消订阅事件
实际上,我正在尝试通过从我的ViewModel
触发事件来关闭我的窗口。 一切都很好,但我知道必须取消订阅我的事件以避免内存泄漏。 因此,我实现了IDisposable
接口,并在Dispose
方法中取消订阅事件。
下面是我的代码:
public partial class MainWindow : Window, IDisposable { private MainViewModel viewModel; public MainWindow() { InitializeComponent(); DataContext = viewModel = new MainViewModel(); this.viewModel.RequestClose += CloseWindow; } void CloseWindow(object sender, EventArgs e) { this.Close(); } public void Dispose() { ////here we need to unsubscribe the event this.viewModel.RequestClose -= this.CloseWindow; } }
我需要知道的是:
- 那个代码是正确的吗?
GC
何时调用并执行dispose方法?- 是否有更好的方法来做这件事?
admin 更改状态以发布 2023年5月23日
但我知道,我必须取消订阅我的事件以避免内存泄漏。
内存泄漏会在短暂存在的对象订阅了长期存在的对象(或静态事件),并且后来没有取消订阅时发生(例如,请参见 这个 答案)。我想,这不是你的情况。
当GC被调用并执行dispose方法时
GC不会调用IDisposable.Dispose
(例如,请参见这个答案)。从来不会。
如果你没有任何代码显式地调用MainWindow.Dispose
,它将永远不会被调用。
有没有更好的方法来做这样的事情?
我会避免使用IDisposable
和事件。我认为这里的附加行为更方便(至少,这是可重用的):
public static class WindowClosingBehavior { public static bool GetIsClosingInitiated(DependencyObject obj) { return (bool)obj.GetValue(IsClosingInitiatedProperty); } public static void SetIsClosingInitiated(DependencyObject obj, bool value) { obj.SetValue(IsClosingInitiatedProperty, value); } public static readonly DependencyProperty IsClosingInitiatedProperty = DependencyProperty.RegisterAttached( "IsClosingInitiated", typeof(bool), typeof(WindowClosingBehavior), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, IsClosingInitiatedChanged)); private static void IsClosingInitiatedChanged(DependencyObject target, DependencyPropertyChangedEventArgs e) { var window = target as Window; if (window != null && (bool)e.NewValue) { window.Close(); } } }
窗口XAML中的某个地方:
behaviors:WindowClosingBehavior.IsClosingInitiated="{Binding IsClosingInitiated}"
其中IsClosingInitiated
是视图模型中的属性:
public class SomeViewModel { // ... private void Foo() { // ... IsClosingInitiated = true; } }