8

क्या होगा यदि आपको समानांतर में एकाधिक एसिंक्रोनस I/O कार्यों को चलाने की आवश्यकता है, लेकिन यह सुनिश्चित करने की आवश्यकता है कि एक ही समय में X I/O प्रक्रियाएं चल रही हों; और पूर्व और पोस्ट I/O प्रसंस्करण कार्यों में ऐसी सीमा नहीं होनी चाहिए।समानांतर में एकाधिक एसिंक कार्यों को ठीक से कैसे चलाएं?

यहां एक परिदृश्य है - मान लें कि 1000 कार्य हैं; उनमें से प्रत्येक इनपुट पैरामीटर के रूप में एक पाठ स्ट्रिंग स्वीकार करता है; उस पाठ को बदलता है (पूर्व I/O प्रसंस्करण) तब लिखता है कि टेक्स्ट को एक फ़ाइल में बदल दिया गया है। लक्ष्य प्री-प्रसंस्करण तर्क 100% सीपीयू/कोर और आई/ओ भाग का उपयोग अधिकतम 10 डिग्री समांतरता के साथ चलाने के लिए करना है (अधिकतम 10 एक साथ फाइल लिखने के लिए एक साथ खोला जाता है)।

क्या आप नमूना कोड प्रदान कर सकते हैं इसे सी #/.NET 4.5 के साथ कैसे किया जाए?

http://blogs.msdn.com/b/csharpfaq/archive/2012/01/23/using-async-for-file-access-alan-berman.aspx

+0

आरएक्स 2.0 इस के लिए बिल्कुल उपयुक्त (एक समय में 10 के लिए दूसरे चरण थ्रॉटल) हो सकता है, लेकिन मैं काफी परिचित नहीं हूँ निश्चित रूप से यह कहने के लिए। : -/ –

उत्तर

7

मुझे लगता है कि इसके लिए टीपीएल डेटाफ्लो का उपयोग करना एक अच्छा विचार होगा: आप असंबद्ध समांतरता के साथ प्री-और पोस्ट-प्रोसेस ब्लॉक बनाते हैं, सीमित समानांतरता वाले फ़ाइल-लेखन ब्लॉक और उन्हें एक साथ जोड़ते हैं। कुछ की तरह:

var unboundedParallelismOptions = 
    new ExecutionDataflowBlockOptions 
    { 
     MaxDegreeOfParallelism = DataflowBlockOptions.Unbounded 
    }; 

var preProcessBlock = new TransformBlock<string, string>(
    s => PreProcess(s), unboundedParallelismOptions); 

var writeToFileBlock = new TransformBlock<string, string>(
    async s => 
      { 
       await WriteToFile(s); 
       return s; 
      }, 
    new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 10 }); 

var postProcessBlock = new ActionBlock<string>(
    s => PostProcess(s), unboundedParallelismOptions); 

var propagateCompletionOptions = 
    new DataflowLinkOptions { PropagateCompletion = true }; 

preProcessBlock.LinkTo(writeToFileBlock, propagateCompletionOptions); 
writeToFileBlock.LinkTo(postProcessBlock, propagateCompletionOptions); 

// use something like await preProcessBlock.SendAsync("text") here 

preProcessBlock.Complete(); 
await postProcessBlock.Completion; 

कहाँ WriteToFile() ऐसा दिखाई दे सकता:

private static async Task WriteToFile(string s) 
{ 
    using (var writer = new StreamWriter(GetFileName())) 
     await writer.WriteAsync(s); 
} 
+0

+1 यह दिलचस्प है .. धन्यवाद! –

+0

यहां 'प्रीप्रोसेस' और 'पोस्टप्रोसेस' विधियां क्या हैं? – shashwat

+0

@shashwat वे जो भी आवश्यक हैं करते हैं। मूल प्रश्न "पूर्व और पोस्ट I/O प्रसंस्करण कार्यों" के बारे में बात करता है, इसलिए मैंने विधियों का उपयोग करके प्रतिनिधित्व किया। – svick

1

ऐसा लगता है कि आप कार्यों की शुरुआत तक पहुँच को नियंत्रित करने के लिए एक Djikstra सेमाफोर पर विचार करना चाहते चाहते हैं।

हालांकि, यह एक ठेठ कतार/उपभोक्ताओं की तरह की निश्चित समस्या की तरह लगता है, जो इसे संरचित करने का एक और उचित तरीका हो सकता है।