2011-12-19 18 views
6

मेरे पास कोड का एक टुकड़ा है जो Parallel.ForEach का उपयोग कर रहा है, शायद आरएक्स एक्सटेंशन या टास्क समांतर लाइब्रेरी के पुराने संस्करण पर आधारित है। मैंने आरएक्स एक्सटेंशन का एक मौजूदा संस्करण स्थापित किया लेकिन Parallel.ForEach नहीं मिला। मैं पुस्तकालय के किसी भी अन्य फैंसी सामान का उपयोग कर रहा है और सिर्फ इस तरह समानांतर में कुछ डेटा की प्रक्रिया करना चाहते हैं:आरएक्स एक्सटेंशन: समानांतर कहां है। के लिए?

Parallel.ForEach(records, ProcessRecord); 

मैं this question पाया, लेकिन मैं आरएक्स के एक पुराने संस्करण पर निर्भर नहीं करना चाहते हैं। लेकिन मैं आरएक्स के लिए कुछ ऐसा नहीं ढूंढ पाया, तो वर्तमान आरएक्स संस्करण का उपयोग करने के लिए वर्तमान और सबसे सीधा आगे क्या तरीका है? परियोजना .NET 3.5 का उपयोग कर रही है।

records.ToObservable() 
    .SelectMany(x => Observable.Start(() => ProcessRecord(x), Scheduler.ThreadPoolScheduler)) 
    .ToList() 
    .First(); 

(या, यदि आप चाहते हैं पर बनाए रखा आइटम के आदेश:

class Parallel 
{ 
    public static void ForEach<T>(IEnumerable<T> source, Action<T> body) 
    { 
     if (source == null) 
     { 
      throw new ArgumentNullException("source"); 
     } 
     if (body == null) 
     { 
      throw new ArgumentNullException("body"); 
     } 
     var items = new List<T>(source); 
     var countdown = new CountdownEvent(items.Count); 
     WaitCallback callback = state => 
     { 
      try 
      { 
       body((T)state); 
      } 
      finally 
      { 
       countdown.Signal(); 
      } 
     }; 
     foreach (var item in items) 
     { 
      ThreadPool.QueueUserWorkItem(callback, item); 
     } 
     countdown.Wait(); 
    } 
} 
+2

.NET 4.0 में अपग्रेड करें? – dtb

+0

संभावित डुप्लिकेट [समानांतर। .NET 3.5 के लिए प्रतिक्रियाशील एक्सटेंशन से अनुपलब्ध है] (http://stackoverflow.com/questions/7398962/parallel-foreach-missing-from-reactive-extensions-for-net-3-5) –

+1

@ हसन: मैंने आपके द्वारा उल्लिखित प्रश्न से जुड़ा हुआ है, इसलिए मुझे इसके बारे में पता था। लेकिन जवाब पुराने आरएक्स संस्करण का उपयोग करने का प्रस्ताव कर रहा है, जिसे मैं उपयोग नहीं करना चाहता हूं। – Achim

उत्तर

24

अगर आप आरएक्स है यह सब मूर्ख goosery ऐसा करने के लिए कोई ज़रूरत नहीं:

+0

किसी भी समय किसी आइटम को केवल प्रोसेस करने के लिए आप इसे थ्रॉटल करने के बारे में कैसे जाएंगे? मैं सैकड़ों वस्तुओं के साथ यह कोशिश कर रहा हूं और यह उन सभी को एक साथ करने की कोशिश कर रहा है जो मेरे ऐप में बड़ी मेमोरी समस्याओं का कारण बन रहा है। मैं इसे एक समय में 5 करने के लिए प्रतिबंधित करने में सक्षम होना चाहता हूं। – Clint

+2

सीमित समवर्तीकरण को शामिल करने के लिए अपडेट किया गया –

1

यहाँ एक सरल प्रतिस्थापन है दक्षता की लागत):

records.ToObservable() 
    .Select(x => Observable.Start(() => ProcessRecord(x), Scheduler.ThreadPoolScheduler)) 
    .Concat() 
    .ToList() 
    .First(); 

या आप एक ही समय में कितने आइटम को सीमित करना चाहते हैं:

records.ToObservable() 
    .Select(x => Observable.Defer(() => Observable.Start(() => ProcessRecord(x), Scheduler.ThreadPoolScheduler))) 
    .Merge(5 /* at a time */) 
    .ToList() 
    .First(); 
+0

यह प्रमोशन दिखता है, लेकिन कोड को कैसे पता चलता है जब सभी आइटम संसाधित किए जाते हैं? समांतर। सभी ब्लॉक तक संसाधित होने तक प्रत्येक ब्लॉक को संसाधित किया जाता है, इसलिए मुझे इसकी परवाह नहीं है। – Achim

+1

यह स्पष्ट रूप से समानांतर का एक सरलीकरण है। फोरेच करता है। जब तक सभी वस्तुओं को संसाधित नहीं किया जाता है तब तक मैंने अपना जवाब ब्लॉक तक बढ़ा दिया है। – dtb

+2

4.0 पर अपग्रेड करने की तुलना में व्यापार-बंद क्या है, इस पर विचार करने लायक है। 'समानांतर' फोरेच 'के लेखकों ने ओवरहेड की मात्रा में समेकन की डिग्री का एक अच्छा संतुलन प्राप्त करने में बहुत काम किया है। दूसरी तरफ @ डीटीबी ने एक अच्छा जवाब दिया जो लगभग 30 एलओसी लेता है। अगर आपको यह उत्तर मिलता है तो आपको अच्छी तरह से ज़रूरत होती है, फिर खुश दिन। यदि आप खुद को ट्वीकिंग और ट्वीकिंग पाते हैं और कोड यहां सैकड़ों एलओसी तक बढ़ रहा है, तो अब आपके पास एक अच्छा लघु संस्करण नहीं मिला है, लेकिन एक बुरा लंबा संस्करण है जहां आप अनिवार्य रूप से 4.0 से अधिक समानांतर ' परीक्षण किया है –

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