Parallel.ForEach()
के पीछे पूरे विचार आप धागे का एक सेट और संग्रह के प्रत्येक धागा प्रक्रियाओं हिस्सा होता है। जैसा कि आपने देखा है, यह async
- await
के साथ काम नहीं करता है, जहां आप एसिंक कॉल की अवधि के लिए थ्रेड जारी करना चाहते हैं।
ForEach()
धागे को अवरुद्ध करके आप "ठीक" कर सकते हैं, लेकिन यह async
- await
के पूरे बिंदु को हरा देता है।
Parallel.ForEach()
के बजाय TPL Dataflow का उपयोग करने के लिए आप क्या कर सकते हैं, जो एसिंक्रोनस Task
एस का समर्थन करता है।
विशेष रूप से, अपने कोड एक TransformBlock
कि async
लैम्ब्डा का उपयोग कर एक Customer
में प्रत्येक आईडी बदल देती का उपयोग कर लिखा जा सकता है। इस ब्लॉक को समानांतर में निष्पादित करने के लिए कॉन्फ़िगर किया जा सकता है। आप उस ब्लॉक को ActionBlock
से लिंक करेंगे जो कंसोल पर प्रत्येक Customer
लिखता है। आप ब्लॉक नेटवर्क सेट करने के बाद, आप कर सकते हैं Post()
TransformBlock
करने के लिए प्रत्येक आईडी।
कोड में:
var ids = new List<string> { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" };
var getCustomerBlock = new TransformBlock<string, Customer>(
async i =>
{
ICustomerRepo repo = new CustomerRepo();
return await repo.GetCustomer(i);
}, new ExecutionDataflowBlockOptions
{
MaxDegreeOfParallelism = DataflowBlockOptions.Unbounded
});
var writeCustomerBlock = new ActionBlock<Customer>(c => Console.WriteLine(c.ID));
getCustomerBlock.LinkTo(
writeCustomerBlock, new DataflowLinkOptions
{
PropagateCompletion = true
});
foreach (var id in ids)
getCustomerBlock.Post(id);
getCustomerBlock.Complete();
writeCustomerBlock.Completion.Wait();
हालांकि आप शायद कुछ छोटे निरंतर करने के लिए TransformBlock
की समानांतरवाद सीमित करना चाहते हैं। इसके अलावा, आप TransformBlock
की क्षमता को सीमित कर सकते हैं और आइटम को SendAsync()
का उपयोग करके असीमित रूप से जोड़ सकते हैं, उदाहरण के लिए यदि संग्रह बहुत बड़ा है।
एक अतिरिक्त लाभ के रूप में जब अपने कोड की तुलना में (अगर यह काम किया) कि लेखन जैसे ही एक आइटम समाप्त हो गया है शुरू कर देंगे, और जब तक प्रसंस्करण के सभी समाप्त हो गया है के लिए इंतजार नहीं है।
एक बहुत ही संक्षिप्त सिंहावलोकन, प्रतिक्रियाशील एक्सटेंशन, TPL और TPL dataflow - http://vantsuyoshi.wordpress.com/2012/01/05/जब-टू-यूज-टीपीएल-एसिंक-रीएक्टिव-एक्सटेंशन-टीपीएल-डेटाफ्लो/मेरे जैसे लोगों के लिए जिन्हें कुछ स्पष्टता की आवश्यकता हो सकती है। –
मुझे पूरा यकीन है कि यह उत्तर प्रसंस्करण को समानांतर नहीं करता है। मेरा मानना है कि आपको समानांतर करने की ज़रूरत है। आईडी पर आचरण करें और उनको पोस्ट करें कस्टमरब्लॉक पर पोस्ट करें। जब मैंने इस सुझाव का परीक्षण किया तो कम से कम यही मिला। – JasonLind
@ जेसनलिंड यह वास्तव में करता है। समांतर में 'समानांतर। फ़ॉरएच() 'से' पोस्ट()' आइटम का उपयोग करना कोई वास्तविक प्रभाव नहीं होना चाहिए। – svick