2015-08-13 38 views
10

可以說我有類一個ObservableCollection:退訂中的ObservableCollection事件

CustomClassName testClass = new CustomClassName(); 
ObservableCollection<CustomClassName> collection = new ObservableCollection<CustomClassName>(); 
testClass.SomeEvent += OnSomeEvent; 
collection.add(testClass); 

當我從一個集合中刪除的項目,我是否需要手動從事件退訂(OnSomeEvent)或者我應該離開它了GC? 什麼是退訂的最佳方式?

回答

5

如果您希望收集物品,那麼您需要取消訂閱。

要做到這一點,通常的做法是:

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; 
     } 
    } 
} 
+0

Thnx。什麼是最好的方法?我正在做collectionChanged。 – Sasha

0

你並不需要在正常的情況下退訂。

事件訂戶不能防止出版商testClass)從被收集,但可能發生相反。除了ObservableCollection之外,我看不到任何保留testClass的內容。

testClass.SomeEvent += this.OnSomeEvent; 

testClass是保持this活着,因爲this存儲在testClass.SomeEvent的調用列表(當有SomeEvent這樣OnSomeEvent被調用)。通過訂閱testClass的活動,this不會保持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"); 
} 

輸出:


你可以看看similar question

+0

正常情況下你的意思是什麼? – Sasha

+0

由於+ =運算符可能會「超載」,所以會發生任何事情。如果它只是訂閱一個事件,它應該沒問題。 –

+0

@Sasha我添加了一些代碼,你可以嘗試,如果它是你的情況。 –

相關問題