2015-08-13 19 views
10

phép nói rằng tôi có một ObservableCollection các lớp:Hủy đăng ký từ các sự kiện trong ObservableCollection

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

Khi tôi sẽ xoá các mục từ một bộ sưu tập, làm tôi cần phải tự bỏ đăng ký từ các sự kiện (OnSomeEvent) hay tôi nên rời khỏi nó cho một GC? Và cách tốt nhất để hủy đăng ký là gì?

Trả lời

5

Nếu bạn mong muốn mục của bạn được thu thập thì có bạn cần phải hủy đăng ký.

Để làm như vậy, theo cách thông thường là:

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. Và cách tốt nhất là gì? Tôi đang làm nó trong collectionChanged. – Sasha

0

Bạn không cần phải ngừng đăng ký trong trường hợp bình thường.

Sự kiện thuê bao không thể ngăn chặn sự xuất bản (testClass) từ được thu thập, nhưng ngược lại có thể xảy ra. Tôi không thể thấy bất cứ điều gì giữ hoạt động testClass, ngoại trừ ObservableCollection.

testClass.SomeEvent += this.OnSomeEvent; 

testClass là giữ this sống vì this được lưu trữ trong danh sách gọi testClass.SomeEvent 's (ví dụ rằng OnSomeEvent được gọi khi có một SomeEvent). this sẽ không giữ testClass còn sống bằng cách đăng ký sự kiện của testClass.

Trong đoạn mã sau, các obj được lấy ra từ bộ sưu tập, và nó được thu gom rác thải mà không hủy đăng ký, bạn có thể thử để chạy mã để xem kết quả:

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"); 
} 

Output:

Đúng
False

Bạn có thể xem qua số similar question.

+0

ý bạn là gì? – Sasha

+0

Vì toán tử + = có thể bị "quá tải" nên mọi thứ đều có thể xảy ra. Nếu nó chỉ là đăng ký một sự kiện, nó sẽ ổn thôi. –

+0

@Sasha Tôi đã thêm một số mã, bạn có thể thử nếu đó là trường hợp của bạn. –

Các vấn đề liên quan