C# 对于生存期较短的对象,是否需要取消订阅事件?

C# 对于生存期较短的对象,是否需要取消订阅事件?,c#,wpf,events,event-handling,C#,Wpf,Events,Event Handling,我有一个视图模型,它从某个服务中检索对象,并使其可用于数据绑定。对象正在实现INotifyPropertyChanged。在视图模型中,我正在侦听PropertyChanged事件,以便在修改对象中的某些属性时执行一些内部操作 现在有可能从服务请求一个新对象,完全替换旧对象。考虑到生命周期本质上受到视图模型本身的限制,并且没有其他人持有对它的引用(WPF使用弱侦听器),在这种情况下我是否需要取消订阅对象?当然,我应该这样做,在二传中这样做很简单,但我真的需要这样做吗 您实际上不需要做任何事情,但

我有一个视图模型,它从某个服务中检索对象,并使其可用于数据绑定。对象正在实现INotifyPropertyChanged。在视图模型中,我正在侦听
PropertyChanged
事件,以便在修改对象中的某些属性时执行一些内部操作

现在有可能从服务请求一个新对象,完全替换旧对象。考虑到生命周期本质上受到视图模型本身的限制,并且没有其他人持有对它的引用(WPF使用弱侦听器),在这种情况下我是否需要取消订阅对象?当然,我应该这样做,在二传中这样做很简单,但我真的需要这样做吗

您实际上不需要做任何事情,但在完成时应该将旧对象与事件分离。原因有二

如果对象被垃圾收集并且事件被触发,则需要花费一些时间来确定该对象不再处于活动状态。希望它能从事件处理程序列表中删除。如果没有,下次也会花更多的时间,以此类推

更重要的是,如果旧对象没有被垃圾收集,并且事件被触发,那么您将收到两个事件通知——一个在旧对象中,一个在新对象中。您需要在旧对象中专门处理这种情况(否则,会发生不好的事情)


处理此问题的最简单方法是在完成后从事件中分离。

[…](WPF使用弱侦听器)[…]-您能为此提供参考吗?允许订阅弱事件,但我认为手动订阅
someEvent+=SomeDelegate
不会被覆盖。如果事件订阅/取消订阅是确定的,则坚持简单性。@DHN WPF的绑定管理器使用。上面也提到了。最后,还有:)嗯,不错。谢谢。为了清洁起见,我将在Dispose中实现IDisposable和unsubscribe,因为当您使用MyViewModel时,您仍然有一个双重引用,只有在有理由关闭MyViewModel而不关闭整个过程时,这才会成为一个问题。大多数代码审阅者将坚持使用“myData.PropertyChanged-=DataPropertyChanged;”在setter中,但除非您需要加快垃圾收集速度,否则实际上没有必要这样做。
public class MyViewModel : INotifyPropertyChanged
{
    private DataType myData;
    public DataType MyData
    {
        get { return myData; }
        protected set
        {
            if (value == myData)
                return;

            if (myData != null)
                myData.PropertyChanged -= DataPropertyChanged;
            myData = value;
            myData.PropertyChanged += DataPropertyChanged;

            OnNotifyPropertyChanged("MyData");
        }
    }

    public void UpdateData ()
    {
        MyData = service.GetData();
    }

    // ...
}