7

मैं एक ObservableConcurrentDictionary बनाने की कोशिश कर रहा हूं। इस ऑब्जेक्ट का उपयोग मल्टीथ्रेड किए गए एप्लिकेशन में किया जाएगा, और इसका डेटा नियंत्रण आइटम्ससोर्स प्रॉपर्टी के माध्यम से नियंत्रण को पॉप्युलेट करने के लिए उपयोग किया जाता है। - वास्तव में, यह बिल्कुल काम नहीं करता हैConcurrentDictionary का उपयोग करके एक कस्टम अवलोकन योग्य संग्रह कैसे बनाएं, INotifyCollectionChanged, INotifyPropertyChanged

public sealed class ObservableConcurrentDictionary<TKey, TValue> : ConcurrentDictionary<TKey, TValue>, INotifyCollectionChanged, INotifyPropertyChanged 
{ 
    #region Constructors 

    public ObservableConcurrentDictionary() 
     : base() 
    { 

    } 

    public ObservableConcurrentDictionary(IEnumerable<KeyValuePair<TKey, TValue>> collection) 
     : base(collection) 
    { 

    } 


    public ObservableConcurrentDictionary(IEqualityComparer<TKey> comparer) 
     : base(comparer) 
    { 

    } 


    public ObservableConcurrentDictionary(int concurrencyLevel, int capacity) 
     : base(concurrencyLevel, capacity) 
    { 

    } 


    public ObservableConcurrentDictionary(IEnumerable<KeyValuePair<TKey, TValue>> collection, IEqualityComparer<TKey> comparer) 
     : base(collection, comparer) 
    { 

    } 


    public ObservableConcurrentDictionary(int concurrencyLevel, int capacity, IEqualityComparer<TKey> comparer) 
     : base(concurrencyLevel, capacity, comparer) 
    { 

    } 

    public ObservableConcurrentDictionary(int concurrencyLevel, IEnumerable<KeyValuePair<TKey, TValue>> collection, IEqualityComparer<TKey> comparer) 
     : base(concurrencyLevel, collection, comparer) 
    { 

    } 

    #endregion 

    #region Public Methods 

    public new TValue AddOrUpdate(TKey key, Func<TKey, TValue> addValueFactory, Func<TKey, TValue, TValue> updateValueFactory) 
    { 
     // Stores the value 
     TValue value; 
     // If key exists 
     if (base.ContainsKey(key)) 
     { 
      // Update value and raise event 
      value = base.AddOrUpdate(key, addValueFactory, updateValueFactory); 
      OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace)); 
     } 
     // Else if key does not exist 
     else 
     { 
      // Add value and raise event 
      value = base.AddOrUpdate(key, addValueFactory, updateValueFactory); 
      OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add)); 
     } 
     // Returns the value 
     return value; 
    } 

    public void Clear() 
    { 
     // Clear dictionary 
     base.Clear(); 
     // Raise event 
     OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); 
    } 

    public new TValue GetOrAdd(TKey key, Func<TKey, TValue> valueFactory) 
    { 
     // Stores the value 
     TValue value; 
     // If key exists 
     if (base.ContainsKey(key)) 
      // Get value 
      value = base.GetOrAdd(key, valueFactory); 
     // Else if key does not exist 
     else 
     { 
      // Add value and raise event 
      value = base.GetOrAdd(key, valueFactory); 
      OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add)); 
     } 
     // Return value 
     return value; 
    } 

    public new TValue GetOrAdd(TKey key, TValue value) 
    { 
     // If key exists 
     if (base.ContainsKey(key)) 
      // Get value 
      base.GetOrAdd(key, value); 
     // Else if key does not exist 
     else 
     { 
      // Add value and raise event 
      base.GetOrAdd(key, value); 
      OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add)); 
     } 
     // Return value 
     return value; 
    } 

    public new bool TryAdd(TKey key, TValue value) 
    { 
     // Stores tryAdd 
     bool tryAdd; 
     // If added 
     if (tryAdd = base.TryAdd(key, value)) 
      // Raise event 
      OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add)); 
     // Return tryAdd 
     return tryAdd; 
    } 

    public new bool TryRemove(TKey key, out TValue value) 
    { 
     // Stores tryRemove 
     bool tryRemove; 
     // If removed 
     if (tryRemove = base.TryRemove(key, out value)) 
      // Raise event 
      OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove)); 
     // Return tryAdd 
     return tryRemove; 
    } 

    public bool TryUpdate(TKey key, TValue newValue, TValue comparisonValue) 
    { 
     // Stores tryUpdate 
     bool tryUpdate; 
     // If updated 
     if (tryUpdate = base.TryUpdate(key, newValue, comparisonValue)) 
      // Raise event 
      OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace)); 
     // Return tryUpdate 
     return tryUpdate; 
    } 

    #endregion 

    #region Private Methods 

    private void OnCollectionChanged(NotifyCollectionChangedEventArgs e) 
    { 
     if (CollectionChanged != null) 
      CollectionChanged(this, e); 
    } 

    #endregion 

    #region INotifyCollectionChanged Members 

    public event NotifyCollectionChangedEventHandler CollectionChanged; 

    #endregion 

    #region INotifyPropertyChanged Members 

    public event PropertyChangedEventHandler PropertyChanged; 

    #endregion 
} 

दुर्भाग्य से समाधान के रूप में इरादा काम नहीं करता:

इस कार्यान्वयन मैं के साथ आए हैं है। मैं क्या गलत कर रहा हूं या कोई बेहतर समाधान करने पर कोई विचार मौजूद है?

कृपया ध्यान दें कि मैं पर्यवेक्षण चयन का उपयोग नहीं कर सकता, इसलिए मुझे अपना स्वयं का अवलोकन संग्रह लिखना है।

संपादित करें: कार्य संस्करण नीचे है। उम्मीद है कि यह किसी और समस्या के साथ किसी और की मदद करता है।

public sealed class ObservableConcurrentDictionary<TKey, TValue> : ConcurrentDictionary<TKey, TValue>, INotifyCollectionChanged, INotifyPropertyChanged 
{ 
    public ObservableConcurrentDictionary() 
     : base() 
    { 

    } 

    public ObservableConcurrentDictionary(IEnumerable<KeyValuePair<TKey, TValue>> collection) 
     : base(collection) 
    { 

    } 

    public ObservableConcurrentDictionary(IEqualityComparer<TKey> comparer) 
     : base(comparer) 
    { 

    } 

    public ObservableConcurrentDictionary(int concurrencyLevel, int capacity) 
     : base(concurrencyLevel, capacity) 
    { 

    } 

    public ObservableConcurrentDictionary(IEnumerable<KeyValuePair<TKey, TValue>> collection, IEqualityComparer<TKey> comparer) 
     : base(collection, comparer) 
    { 

    } 

    public ObservableConcurrentDictionary(int concurrencyLevel, int capacity, IEqualityComparer<TKey> comparer) 
     : base(concurrencyLevel, capacity, comparer) 
    { 

    } 

    public ObservableConcurrentDictionary(int concurrencyLevel, IEnumerable<KeyValuePair<TKey, TValue>> collection, IEqualityComparer<TKey> comparer) 
     : base(concurrencyLevel, collection, comparer) 
    { 

    } 

    public new TValue AddOrUpdate(TKey key, Func<TKey, TValue> addValueFactory, Func<TKey, TValue, TValue> updateValueFactory) 
    { 
     // Stores the value 
     TValue value; 
     // If key exists 
     if (base.ContainsKey(key)) 
     { 
      // Update value and raise event 
      value = base.AddOrUpdate(key, addValueFactory, updateValueFactory); 
      OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, value)); 
     } 
     // Else if key does not exist 
     else 
     { 
      // Add value and raise event 
      value = base.AddOrUpdate(key, addValueFactory, updateValueFactory); 
      OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, value)); 
     } 
     // Returns the value 
     return value; 
    } 

    public new void Clear() 
    { 
     // Clear dictionary 
     base.Clear(); 
     // Raise event 
     OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); 
    } 

    public new TValue GetOrAdd(TKey key, Func<TKey, TValue> valueFactory) 
    { 
     // Stores the value 
     TValue value; 
     // If key exists 
     if (base.ContainsKey(key)) 
      // Get value 
      value = base.GetOrAdd(key, valueFactory); 
     // Else if key does not exist 
     else 
     { 
      // Add value and raise event 
      value = base.GetOrAdd(key, valueFactory); 
      OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, value)); 
     } 
     // Return value 
     return value; 
    } 

    public new TValue GetOrAdd(TKey key, TValue value) 
    { 
     // If key exists 
     if (base.ContainsKey(key)) 
      // Get value 
      base.GetOrAdd(key, value); 
     // Else if key does not exist 
     else 
     { 
      // Add value and raise event 
      base.GetOrAdd(key, value); 
      OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, value)); 
     } 
     // Return value 
     return value; 
    } 

    public new bool TryAdd(TKey key, TValue value) 
    { 
     // Stores tryAdd 
     bool tryAdd; 
     // If added 
     if (tryAdd = base.TryAdd(key, value)) 
      // Raise event 
      OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, value)); 
     // Return tryAdd 
     return tryAdd; 
    } 

    public new bool TryRemove(TKey key, out TValue value) 
    { 
     // Stores tryRemove 
     bool tryRemove; 
     // If removed 
     if (tryRemove = base.TryRemove(key, out value)) 
      // Raise event 
      OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, value)); 
     // Return tryAdd 
     return tryRemove; 
    } 

    public new bool TryUpdate(TKey key, TValue newValue, TValue comparisonValue) 
    { 
     // Stores tryUpdate 
     bool tryUpdate; 
     // If updated 
     if (tryUpdate = base.TryUpdate(key, newValue, comparisonValue)) 
      // Raise event 
      OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, newValue)); 
     // Return tryUpdate 
     return tryUpdate; 
    } 

    private void OnCollectionChanged(NotifyCollectionChangedEventArgs e) 
    { 
     if (CollectionChanged != null) 
      CollectionChanged(this, e); 
    } 

    public event NotifyCollectionChangedEventHandler CollectionChanged; 

    public event PropertyChangedEventHandler PropertyChanged; 
} 
+0

"यह बिल्कुल काम नहीं करता है" - वैध समस्या विवरण नहीं है। कृपया हमें बताएं कि आपको कौन सी त्रुटियां मिल रही हैं, आप इसका परीक्षण करने के लिए किस कोड का उपयोग कर रहे हैं और आपका कारण है कि आप ObservableCollection का उपयोग क्यों नहीं कर सकते। – Euphoric

उत्तर

2

जल्दी अपनी तरफ से किसी भी eplanation मैं केवल अनुमान लगा सकते हैं बिना अपने कोड के माध्यम से जा। मुझे नहीं लगता कि NotifyCollectionChangedEventArgs पर सेटिंग एक्शन पर्याप्त है। NewItems, OldItems गुण भी हैं, जो ग्राहक को बताते हैं कि कौन सी चीजें बदली गई हैं।

यह भी ध्यान रखें कि, जबकि संग्रह हैं, कई WPF घटक डेटाबाइंडिंग के माध्यम से एक समय में केवल एक आइटम परिवर्तन का समर्थन करते हैं।

+0

अस्पष्ट विवरण के लिए मेरी माफ़ी। कल एक लंबा और निराशाजनक दिन था। तुमने मुझे सही दिशा में ले जाया। हर समय सही ढंग से काम कर रहे हैं। धन्यवाद! – c0D3l0g1c

11

मैं ओपी नमूना काम करने में सक्षम नहीं था। क्रॉस थ्रेडिंग अपवादों का एक ट्रंक भार उठाया, हर बार कोई फर्क नहीं पड़ता कि मैंने क्या प्रयास किया।

हालांकि, के बाद से मैं एक धागा सुरक्षित संग्रह की जरूरत है कि INotifyCollectionChanged और INotifyPropertyChanged इंटरफेस को लागू करता है में भी था, मैं आसपास googled और माइक्रोसॉफ्ट खुद को पर लोगों से एक कार्यान्वयन पाया।

इस फ़ाइल को http://code.msdn.microsoft.com/Samples-for-Parallel-b4b76364 डाउनलोड करें और संग्रह में ObservableConcurrentDictionary.cs खोजें।

एक आकर्षण की तरह काम करता है!

+1

उस लिंक ने अभी मेरी जिंदगी बदल दी है। धन्यवाद :) – Quanta

1

मैं एक ObservableConcurrentDictionnary की एक तंग संस्करण का विकास किया, टिप्पणी कृपया/सुझाव है ...

... जहां TValue: ऑब्जेक्ट {वस्तु के बजाय अपने वर्ग का उपयोग करें ...}

कुरलेट

using System; 
using System.Collections.Concurrent; 
using System.Collections.Generic; 
using System.Collections.Specialized; 
using System.ComponentModel; 

namespace Collections 
{ 
    public class ObservableConcurrentDictionary<TValue> : ConcurrentDictionary<Int32, TValue>, INotifyCollectionChanged, INotifyPropertyChanged 
     where TValue : Object , new() 
    { 
     public event NotifyCollectionChangedEventHandler CollectionChanged; 
     protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs changeAction) 
     { 
      var eh = CollectionChanged; 
      if (eh == null) return; 

      eh(this, changeAction); 

      OnPropertyChanged(); 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 
     private void OnPropertyChanged() 
     { 
      var eh = PropertyChanged; 
      if (eh == null) return; 

      // All properties : Keys, Values, Count, IsEmpty 
      eh(this, new PropertyChangedEventArgs(null)); 
     } 

     #region Ctors 
     public ObservableConcurrentDictionary() 
      : base() 
     { 

     } 

     public ObservableConcurrentDictionary(IEnumerable<KeyValuePair<Int32, TValue>> collection) 
      : base(collection) 
     { 

     } 

     public ObservableConcurrentDictionary(IEqualityComparer<Int32> comparer) 
      : base(comparer) 
     { 

     } 

     public ObservableConcurrentDictionary(int concurrencyLevel, int capacity) 
      : base(concurrencyLevel, capacity) 
     { 

     } 

     public ObservableConcurrentDictionary(IEnumerable<KeyValuePair<Int32, TValue>> collection, IEqualityComparer<Int32> comparer) 
      : base(collection, comparer) 
     { 

     } 

     public ObservableConcurrentDictionary(int concurrencyLevel, int capacity, IEqualityComparer<Int32> comparer) 
      : base(concurrencyLevel, capacity, comparer) 
     { 

     } 

     public ObservableConcurrentDictionary(int concurrencyLevel, IEnumerable<KeyValuePair<Int32, TValue>> collection, IEqualityComparer<Int32> comparer) 
      : base(concurrencyLevel, collection, comparer) 
     { 

     } 
     #endregion 

     public new void Clear() 
     { 
      // Clear dictionary 
      base.Clear(); 
      // Raise event 
      OnCollectionChanged(changeAction: new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); 
     } 

     public new TValue AddOrUpdate(Int32 key, Func<Int32, TValue> addValueFactory, 
      Func<Int32, TValue, TValue> updateValueFactory) 
     { 
      bool isUpdated = false; 
      TValue oldValue = default(TValue); 

      TValue value = base.AddOrUpdate(key, addValueFactory, (k, v) => 
      { 
       isUpdated = true; 
       oldValue = v; 
       return updateValueFactory(k, v); 
      }); 

      if (isUpdated) OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, value, oldValue)); 

      OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, value)); 
      return value; 
     } 

     public new TValue AddOrUpdate(Int32 key, TValue addValue, Func<Int32, TValue, TValue> updateValueFactory) 
     { 
      bool isUpdated = false; 
      TValue oldValue = default(TValue); 

      TValue value = base.AddOrUpdate(key, addValue, (k, v) => 
      { 
       isUpdated = true; 
       oldValue = v; 
       return updateValueFactory(k, v); 
      }); 

      if (isUpdated) OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, value, oldValue)); 

      OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, value)); 
      return value; 
     } 

     public new TValue GetOrAdd(Int32 key, Func<Int32, TValue> addValueFactory) 
     { 
      bool isAdded = false; 

      TValue value = base.GetOrAdd(key, k => 
      { 
       isAdded = true; 
       return addValueFactory(k); 
      }); 

      if (isAdded) OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, value)); 

      return value; 
     } 

     public new TValue GetOrAdd(Int32 key, TValue value) 
     { 
      return GetOrAdd(key, k => value); 
     } 

     public new bool TryAdd(Int32 key, TValue value) 
     { 
      bool tryAdd = base.TryAdd(key, value); 

      if (tryAdd) OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, value)); 

      return tryAdd; 
     } 

     public new bool TryRemove(Int32 key, out TValue value) 
     { 
      // Stores tryRemove 
      bool tryRemove = base.TryRemove(key, out value); 

      // If removed raise event 
      if (tryRemove) OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, value)); 

      return tryRemove; 
     } 

     public new bool TryUpdate(Int32 key, TValue newValue, TValue comparisonValue) 
     { 
      // Stores tryUpdate 
      bool tryUpdate = base.TryUpdate(key, newValue, comparisonValue); 

      if (tryUpdate) OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, newValue, comparisonValue)); 

      return tryUpdate; 
     } 

    } 
} 
संबंधित मुद्दे