2012-05-24 19 views
6

मैं इसे ब्लॉकिंग कोलेक्शन में लपेटकर एक ConcurrentDictionary को कार्यान्वित करने का प्रयास करता हूं लेकिन सफल नहीं हुआ।ब्लॉकिंग कोलेक्शन में ConcurrentDictionary को कैसे लपेटें?

मैं समझता हूँ कि एक चर घोषणाओं, आदि BlockingCollection जैसे ConcurrentBag<T>, ConcurrentQueue<T> के साथ काम

तो, एक ConcurrentBag एक BlockingCollection में लिपटे बनाने के लिए मैं घोषणा करेंगे और इस तरह का दृष्टांत:

BlockingCollection<int> bag = new BlockingCollection<int>(new ConcurrentBag<int>()); 

लेकिन ConcurrentDictionary के लिए यह कैसे करें? मुझे निर्माता और उपभोक्ता पक्ष दोनों पर ब्लॉकिंग कोलेक्शन की अवरुद्ध कार्यक्षमता की आवश्यकता है।

+0

शब्दकोश (और ConcurrentDictionary भी) वस्तुओं के क्रम को सुरक्षित नहीं करता है। क्या आप अपने निर्माता-उपभोक्ता परिदृश्य का वर्णन कर सकते हैं? – Dennis

+0

@ डेनिस, मुझे इसके बारे में पता है। एक निर्माता स्टोर समवर्ती डिक्शनरी में KeyValuePairs, और एक उपभोक्ता कार्य एक int बढ़ाता है और संबंधित कुंजी के साथ int मिलान करता है तो KeyValuePair को हटा देता है। मैं ऐसा इसलिए करता हूं क्योंकि कार्यकर्ता कार्य समवर्ती डिक्शनरी को मानों के साथ पॉप्युलेट करते हैं लेकिन मनमाने ढंग से क्रम में, उपभोक्ता कार्य सुनिश्चित करता है कि प्राप्त मूल्य सही क्रम में चालू/काम किए जाते हैं। क्या एक ConcurrentDictionary को ब्लॉकिंग कोलेक्शन में लपेटा जा सकता है? –

+0

आप किस समाधान के साथ आए थे? मैं एक समान समस्या का अच्छा समाधान खोजने की कोशिश कर रहा हूं जहां निर्माता उपभोक्ता द्वारा आवश्यक आदेश में वस्तुओं का उत्पादन नहीं करता है। (पुरानी पोस्ट मुझे पता है, लेकिन यह एक कोशिश के लायक है) – Kim

उत्तर

1

आप अपनी खुद की एडाप्टर वर्ग लिखने के लिए की आवश्यकता होगी - तरह कुछ:

public class ConcurrentDictionaryWrapper<TKey,TValue> : IProducerConsumerCollection<KeyValuePair<TKey,TValue>> 
{ 
    private ConcurrentDictionary<TKey, TValue> dictionary; 

    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() 
    { 
     return dictionary.GetEnumerator(); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 

    public void CopyTo(Array array, int index) 
    { 
     throw new NotImplementedException(); 
    } 

    public int Count 
    { 
     get { return dictionary.Count; } 
    } 

    public object SyncRoot 
    { 
     get { return this; } 
    } 

    public bool IsSynchronized 
    { 
     get { return true; } 
    } 

    public void CopyTo(KeyValuePair<TKey, TValue>[] array, int index) 
    { 
     throw new NotImplementedException(); 
    } 

    public bool TryAdd(KeyValuePair<TKey, TValue> item) 
    { 
     return dictionary.TryAdd(item.Key, item.Value); 
    } 

    public bool TryTake(out KeyValuePair<TKey, TValue> item) 
    { 
     item = dictionary.FirstOrDefault(); 
     TValue value; 
     return dictionary.TryRemove(item.Key, out value); 
    } 

    public KeyValuePair<TKey, TValue>[] ToArray() 
    { 
     throw new NotImplementedException(); 
    } 
} 
+1

कोड सुझाव के लिए धन्यवाद। लेकिन ब्लॉकिंग कोलेक्शन का उपयोग करने में मेरा मुख्य उद्देश्य संग्रह को जोड़ने के रूप में संग्रह को चिह्नित करने की क्षमता थी और इसके बारे में स्थिति की जांच करने के साथ-साथ ब्लॉकिंग कोलेक्शन प्रदान करने के समान, चाहे वह पूर्ण और खाली हो। मुझे पता है कि मैं आसानी से ऐसी कार्यक्षमता जोड़ सकता हूं, लेकिन मैं एक सुझाव की तलाश कर रहा हूं कि इसे ब्लॉकिंग कोलेक्शन के माध्यम से सीधे कैसे किया जाए। अब तक मुझे कोई कारण नहीं दिख रहा है कि यह सीधे ब्लॉकिंग संग्रह के माध्यम से क्यों काम नहीं कर सकता है। शायद यह केवल IProducerConsumerCollection लेता है? –

4

शायद तुम blockingCollection

 ConcurrentDictionary<int, BlockingCollection<string>> mailBoxes = new ConcurrentDictionary<int, BlockingCollection<string>>(); 
     int maxBoxes = 5; 

     CancellationTokenSource cancelationTokenSource = new CancellationTokenSource(); 
     CancellationToken cancelationToken = cancelationTokenSource.Token; 

     Random rnd = new Random(); 
     // Producer 
     Task.Factory.StartNew(() => 
     { 
      while (true) 
      { 
       int index = rnd.Next(0, maxBoxes); 
       // put the letter in the mailbox 'index' 
       var box = mailBoxes.GetOrAdd(index, new BlockingCollection<string>()); 
       box.Add("some message " + index, cancelationToken); 
       Console.WriteLine("Produced a letter to put in box " + index); 

       // Wait simulating a heavy production item. 
       Thread.Sleep(1000); 
      } 
     }); 

     // Consumer 1 
     Task.Factory.StartNew(() => 
     { 
      while (true) 
      { 
       int index = rnd.Next(0, maxBoxes); 
       // get the letter in the mailbox 'index' 
       var box = mailBoxes.GetOrAdd(index, new BlockingCollection<string>()); 
       var message = box.Take(cancelationToken); 
       Console.WriteLine("Consumed 1: " + message); 

       // consume a item cost less than produce it: 
       Thread.Sleep(50); 
      } 
     }); 

     // Consumer 2 
     Task.Factory.StartNew(() => 
     { 
      while (true) 
      { 
       int index = rnd.Next(0, maxBoxes); 
       // get the letter in the mailbox 'index' 
       var box = mailBoxes.GetOrAdd(index, new BlockingCollection<string>()); 
       var message = box.Take(cancelationToken); 
       Console.WriteLine("Consumed 2: " + message); 

       // consume a item cost less than produce it: 
       Thread.Sleep(50); 
      } 
     }); 

     Console.ReadLine(); 
     cancelationTokenSource.Cancel(); 

की समवर्ती शब्दकोश की जरूरत है इस तरह से, एक उपभोक्ता जो कुछ उम्मीद कर रही है तक मेलबॉक्स 5 में, जब तक उत्पादक मेलबॉक्स 5 में कोई पत्र नहीं डालता तब तक इंतजार करेगा।

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