2014-08-04 6 views
5

पर कॉल करता हूं, मुझे आईओसीपी के बारे में कुछ पता है, लेकिन मैं एपीएम के साथ थोड़ा उलझन में हूं।, दो धागे हैं जब मैं BeginXXX

static FileStream fs; 
static void Main(string[] args) 
{ 
    fs = new FileStream(@"c:\bigfile.txt", FileMode.Open); 
    var buffer = new byte[10000000]; 
    IAsyncResult asyncResult = fs.BeginRead(buffer, 0, 10000000, OnCompletedRead, null); 
    Console.WriteLine("async..."); 
    int bytesRead = fs.EndRead(asyncResult); 
    Console.WriteLine("async... over"); 
} 

static void OnCompletedRead(IAsyncResult ar) 
{ 
     Console.WriteLine("finished"); 
} 

मुझे आश्चर्य है, पढ़ने के लिए कार्रवाई एक आईओ धागा एसिंक्रोनस रूप द्वारा निष्पादित है? या एक थ्रेड पूल में एक कार्यकर्ता धागा?

और कॉलबैक फ़ंक्शन OnCompletedRead, क्या इसे सीएलआर थ्रेड पूल में आईओ थ्रेड द्वारा भी निष्पादित किया गया है?

क्या ये दो धागे एक ही हैं? यदि नहीं, तो दो धागे उत्पन्न होते हैं, एक पढ़ी कार्रवाई निष्पादित करता है और दूसरा कॉलबैक करता है।

+0

आपको 'Main' के अंदर 'EndReceive' को कॉल नहीं करना चाहिए। आपको इसे 'ऑनकंपलेट रीड' में कॉल करना चाहिए अन्यथा आपको एसिंक कॉल के किसी भी लाभ नहीं मिल रहे हैं। –

+3

मैं http://blog.stephencleary.com/2013/11/there-is-no-thread.html –

+0

पढ़ने की भी सिफारिश करता हूं, मैंने उस ब्लॉग को पढ़ा। तो पढ़ने की प्रक्रिया को संसाधित करने के लिए कोई धागा नहीं है। लेकिन कॉलबैक आईओ थ्रेड पर निष्पादित करता है, क्या मैं सही हूँ? –

उत्तर

5

यदि आप BeginRead के साथ AsyncCallback तर्क का उपयोग नहीं करते हैं तो केवल एक थ्रेड है जो आपके प्रोग्राम में कोड चलाता है। आईओ थ्रेड पूल में थ्रेड पर कोड की थोड़ी सी मात्रा चलाकर आईओ पूरा होने के बाद आईओ पूरा होने वाले बंदरगाहों को सिग्नल करने के लिए आईओ पूरा करने के बंदरगाहों का उपयोग करता है। जब आप EndRead को कॉल करते हैं तो यह वर्तमान थ्रेड को अवरुद्ध कर देगा जब तक कि आईओ ऑपरेशन पूरा न हो जाए। जब आप रीड ऑपरेशन शुरू करते हैं तो यह अतुल्यकालिक होता है कि वर्तमान थ्रेड को आईओ हार्डवेयर को पढ़ने के संचालन के लिए इंतजार करने के अलावा कुछ भी करने की आवश्यकता नहीं होती है, इसलिए आप इस दौरान अन्य चीजें कर सकते हैं और फिर तय कर सकते हैं कि आप कब रुकना चाहते हैं और आईओ खत्म करने के लिए प्रतीक्षा करें।

यदि आप एक AsyncCallback में पास करते हैं तो जब आईओ ऑपरेशन पूरा हो जाता है तो यह एक आईओ थ्रेड पूल थ्रेड पर कोड की एक छोटी राशि निष्पादित करेगा जो आपकी कॉलबैक विधि को .NET थ्रेड पूल से थ्रेड पर निष्पादित करने के लिए ट्रिगर करेगा ।

+0

तो OnCompletedRead I/O थ्रेड पर निष्पादित करें ?? –

+0

का मतलब है कि कॉलबैक फ़ंक्शन मुख्य थ्रेड द्वारा निकाला जाता है? वास्तव में? मुझे ऐसा नहीं लगता। –

+0

@roast_soul यह 'BeginXxxxx' के कार्यान्वयन पर निर्भर करता है, कुछ विधियां सिंक्रनाइज़ेशन संदर्भ को कैप्चर करती हैं और संदर्भ में थ्रेड पर कॉल को वापस चलाती हैं, अन्य लोग थियोपूल थ्रेड का उपयोग करेंगे जब आईओ पूरा करने वाला पोर्ट संकेत करता है कि डेटा तैयार है । इसे [एपीएम] (http://msdn.microsoft.com/en-us/library/ms228963 (v = vs.110) .aspx में परिभाषित नहीं किया गया है) async/await के विपरीत जो हमेशा 'सिंक्रनाइज़ेशन कॉन्टेक्स्ट' की जांच करता है आप इसे 'ConfigureAwait (false)' के साथ नहीं बताते हैं। –

2

आमतौर पर, एमक्लासन आईओ बाध्य काम, आईओसीपी और एपीएम की प्रकृति के बारे में सही है। जब BeginRead निष्पादित होता है, तो यह कर्नेल मोड में सभी तरह से असीमित रूप से नीचे आता है। लेकिन, विशेष रूप से आपके उदाहरण में एक चेतावनी है कि उन्होंने अपने जवाब में उल्लेख नहीं किया।

आपके उदाहरण में, आप FileStream कक्षा का उपयोग करते हैं। एक महत्वपूर्ण नोट करने के लिए बात यह है कि आप FileStream अधिभार कि एक useAsync बूलियन स्वीकार करता है का उपयोग करें, जब आप एक BeginWrite/EndWrite आपरेशन, यह कतार काम आह्वान एक नया ThreadPool धागा पर न हो।

यह उचित अधिभार है:

public FileStream(
    string path, 
    FileMode mode, 
    FileAccess access, 
    FileShare share, 
    int bufferSize, 
    bool useAsync 
) 

MSDN से:

useAsync:

प्रकार: System.Boolean

निर्दिष्ट करता है कि क्या अतुल्यकालिक मैं उपयोग करने के लिए/ओ या तुल्यकालिक I/O। हालांकि, ध्यान दें कि अंतर्निहित ऑपरेटिंग सिस्टम असीमित I/O का समर्थन नहीं कर सकता है, इसलिए जब सत्य निर्दिष्ट करते हैं, हैंडल प्लेटफ़ॉर्म के आधार पर सिंक्रनाइज़ रूप से खोला जा सकता है। जब असीमित रूप से खोला जाता है, तो BeginRead और BeginWrite विधियां बड़े पढ़ने या लिखने पर बेहतर प्रदर्शन करती हैं, लेकिन छोटे पढ़ने या लिखने के लिए वे बहुत धीमे हो सकते हैं। यदि एप्लिकेशन को एसिंक्रोनस I/O का लाभ लेने के लिए डिज़ाइन किया गया है, तो उपयोग Async पैरामीटर को सत्य पर सेट करें। का उपयोग अतुल्यकालिक मैं/हे सही ढंग से के रूप में ज्यादा 10 का एक कारक के रूप में द्वारा अनुप्रयोगों में तेजी लाने सकता है, लेकिन अतुल्यकालिक मैं के लिए आवेदन पुनः रचना के बिना इसे प्रयोग/हे एक कारक के रूप के रूप में ज्यादा से प्रदर्शन कम कर सकते हैं 10

की

आपको यह सुनिश्चित करना होगा कि एपीएम पैटर्न को लागू करने वाली प्रत्येक विशिष्ट विधि वास्तव में सही असीमित काम का उपयोग करती है।

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