C# 取消订阅observableCollection中的事件

C# 取消订阅observableCollection中的事件,c#,C#,假设我有一个可观察的类集合: CustomClassName testClass = new CustomClassName(); ObservableCollection<CustomClassName> collection = new ObservableCollection<CustomClassName>(); testClass.SomeEvent += OnSomeEvent; collection.add(testClass); CustomClassN

假设我有一个可观察的类集合:

CustomClassName testClass = new CustomClassName();
ObservableCollection<CustomClassName> collection = new ObservableCollection<CustomClassName>();
testClass.SomeEvent += OnSomeEvent;
collection.add(testClass);
CustomClassName testClass=new CustomClassName();
ObservableCollection集合=新的ObservableCollection();
testClass.SomeEvent+=OnSomeEvent;
collection.add(testClass);
当我将从集合中删除项目时,我需要手动取消订阅事件(OnSomeEvent)还是将其留给GC?
取消订阅的最佳方式是什么?

如果您希望收到您的物品,那么是的,您需要取消订阅

为此,通常的方法是:

collection.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(collection_CollectionChanged);

// ...
// and add the method
void collection_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
    if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
    {
        foreach (var it in e.OldItems) {
            var custclass = it as CustomClassName;
            if (custclass != null) custclass.SomeEvent -= OnSomeEvent;
        }
    }
}

在正常情况下你不需要退订

事件订阅服务器无法阻止发布服务器(
testClass
)被收集,但可能发生相反的情况。我看不到任何东西使
testClass
保持活动状态,除了
observedcollection

testClass.SomeEvent += this.OnSomeEvent;
testClass
保持
this
处于活动状态,因为
this
存储在
testClass.SomeEvent
的调用列表中(这样当存在
SomeEvent
时会调用
OnSomeEvent
不会通过订阅
testClass
的事件来保持
testClass
的活动状态

在以下代码中,
obj
将从收集中删除,并在不取消订阅的情况下对其进行垃圾收集,您可以尝试运行代码以查看结果:

void Main()
{
    var obj = new BackgroundWorker();
    obj.DoWork += OnSomeEvent;
    var oc = new ObservableCollection<object>{ obj };

    WeakReference objRef = new WeakReference(obj);
    Console.WriteLine(objRef.IsAlive);

    oc.Remove(obj);
    obj = null;
    GC.Collect();

    Console.WriteLine(objRef.IsAlive);
}

private void OnSomeEvent(object sender, DoWorkEventArgs e)
{   
    Console.WriteLine("work");
}
void Main()
{
var obj=新的BackgroundWorker();
obj.DoWork+=OnSomeEvent;
var oc=新的可观察集合{obj};
WeakReference objRef=新的WeakReference(obj);
Console.WriteLine(objRef.IsAlive);
oc.移除(obj);
obj=null;
GC.Collect();
Console.WriteLine(objRef.IsAlive);
}
SomeEvent上的私有无效(对象发送方,DoWorkEventArgs e)
{   
控制台。写入线(“工作”);
}
输出:

正确
假的


您可以看一看。

Thnx。最好的方法是什么?我是在collectionChanged中完成的。你所说的正常情况是什么意思?因为+=运算符可以“重载”,所以任何事情都可能发生。如果它只是订阅一个事件,那应该没问题。@Sasha我添加了一些代码,如果是你的情况,你可以试试。