2013-02-11 13 views
9

मैं अभी सी # की नई async सुविधाओं के साथ शुरू कर रहा हूं। मैंने समांतर डाउनलोड आदि पर बहुत कुछ पढ़ा है लेकिन टेक्स्ट फ़ाइल को पढ़ने/संसाधित करने पर कुछ भी नहीं है।फ़ाइल पढ़ने के लिए सी # 5.0 एसिंक का उपयोग

मेरे पास एक पुरानी स्क्रिप्ट थी जिसका उपयोग मैं लॉग फ़ाइल फ़िल्टर करने के लिए करता था और मुझे लगा कि मुझे इसे अपग्रेड करने के लिए जाना होगा। हालांकि मुझे यकीन नहीं है कि नए async/await सिंटैक्स का मेरा उपयोग सही है।

मेरे सिर में मैं इसे फ़ाइल लाइन को लाइन से पढ़ता हूं और इसे अलग थ्रेड में प्रोसेसिंग के लिए पास करता हूं ताकि परिणाम के इंतजार किए बिना यह जारी रह सके।

क्या मैं इसके बारे में सही तरीके से सोच रहा हूं, या इसे लागू करने का सबसे अच्छा तरीका क्या है?

static async Task<string[]> FilterLogFile(string fileLocation) 
{ 
    string line; 

    List<string> matches = new List<string>(); 

    using(TextReader file = File.OpenText(fileLocation)) 
    {   
     while((line = await file.ReadLineAsync()) != null) 
     { 
      CheckForMatch(line, matches); 
     } 
    } 

    return matches.ToArray(); 
} 

पूर्ण स्क्रिप्ट: http://share.linqpad.net/29kgbe.linq

+0

बस [msdn docs] (http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx) पर एक नज़र डालें, जिसने यह स्पष्ट किया कि मैं गलत में कीवर्ड के बारे में सोच रहा हूं मार्ग। मुझे नहीं लगता कि इस मामले में प्रदर्शन में सुधार करने के लिए वे बहुत कुछ कर सकते हैं। –

+1

क्या मैं इसकी सिफारिश कर सकता हूं? http://blog.jerrynixon.com/2012/06/windows-8-how-to-read-files-in-winrt.html –

उत्तर

9

मेरे सिर में मैं इस लाइन द्वारा फ़ाइल लाइन पढ़ने और अलग सूत्र में प्रसंस्करण के लिए उस पर से गुजर रहा है, तो यह एक परिणाम का इंतजार किए बिना जारी रख सकते हैं देखते हैं।

लेकिन यह आपका कोड नहीं है। इसके बजाए, जब आप सभी पढ़ा जाता है तो आप (असीमित रूप से) एक सरणी वापस कर देंगे। यदि आप वास्तव में असीमित रूप से मैचों को एक-एक करके वापस करना चाहते हैं, तो आपको कुछ प्रकार के एसिंक्रोनस संग्रह की आवश्यकता होगी। आप इसके लिए टीपीएल डेटाफ्लो से एक ब्लॉक का उपयोग कर सकते हैं। उदाहरण के लिए:

ISourceBlock<string> FilterLogFile(string fileLocation) 
{ 
    var block = new BufferBlock<string>(); 

    Task.Run(async() => 
    { 
     string line; 

     using(TextReader file = File.OpenText(fileLocation)) 
     {   
      while((line = await file.ReadLineAsync()) != null) 
      { 
       var match = GetMatch(line); 

       if (match != null) 
        block.Post(match); 
      } 
     } 

     block.Complete(); 
    }); 

    return block; 
} 

(आपको त्रुटि हैंडलिंग जोड़ने के लिए, शायद लौट आए ब्लॉक दोषयुक्त द्वारा की आवश्यकता होगी।) इसके बाद आप एक और ब्लॉक है कि परिणाम पर कार्रवाई करेंगे करने के लिए लौट ब्लॉक लिंक होगा। या आप उन्हें ब्लॉक से सीधे पढ़ सकते हैं (ReceiveAsync() का उपयोग करके)।


लेकिन पूर्ण कोड को देखते हुए, मुझे यकीन नहीं है कि यह दृष्टिकोण आपके लिए उपयोगी होगा। जिस तरह से आप परिणामों को संसाधित करते हैं (समूहबद्ध करते हैं और फिर प्रत्येक समूह में गिनती करके ऑर्डर करते हैं), आप उनके साथ बहुत कुछ नहीं कर सकते हैं जब तक कि आप सभी में न हों।

+0

इससे अधिक समझदारी होती है। उदाहरण टीपीएल डेटाफ्लो कोड के लिए धन्यवाद। क्या मुझे शायद मैचों की सूची या 'चेकफोरमैच' विधि पर इंतजार करना चाहिए? जैसा कि मैंने कल्पना की है कि यह तुल्यकालिक रूप से चलने से बहुत अलग नहीं है। –

+1

@ सैम आपको केवल 'प्रतीक्षा' का उपयोग करना चाहिए जहां यह समझ में आता है, जो ज्यादातर कोड में है जो आईओ का उपयोग करता है। सिंक्रोनस कोड से यहां अंतर: 1. 'फ़ाइल का इंतजार करें। ReadFileAsync() 'थ्रेड को अवरुद्ध नहीं करता है, इसलिए यह अधिक कुशल है। 2. आप किसी अन्य धागे को अवरुद्ध किए बिना परिणामों को संसाधित कर सकते हैं। – svick

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