2014-10-30 20 views
6

मुझे अभी तक 'एसिंक' नहीं मिलता है और अभी तक प्रतीक्षा नहीं है, और मैं किसी विशेष समस्या के बारे में कुछ स्पष्टीकरण ढूंढ रहा हूं जिसे मैं हल करने वाला हूं। असल में, मुझे कुछ कोड लिखना होगा जो एक टीसीपी कनेक्शन को संभालेगा। यह अनिवार्य रूप से केवल डेटा प्राप्त करेगा और कनेक्शन बंद होने तक इसे संसाधित करेगा।async/await बनाम BeginRead, EndRead

मैं आमतौर पर नेटवर्कस्ट्रीम BeginRead और EndRead पैटर्न का उपयोग करके इस कोड को लिखूंगा, लेकिन चूंकि async/प्रतीक्षा पैटर्न बहुत साफ है, इसलिए मैं इसके बजाय इसका उपयोग करने के लिए लुभाना चाहता हूं। हालांकि, चूंकि मैं स्वीकार करता हूं कि इन्हें वास्तव में पूरी तरह से समझ में नहीं आता है, इसलिए मैं परिणामों से थोड़ा सावधान हूं। क्या कोई दूसरे से अधिक संसाधनों का उपयोग करेगा; क्या कोई एक थ्रेड का उपयोग करेगा जहां कोई अन्य आईओसीपी का उपयोग करेगा, आदि

कनवॉल्यूट उदाहरण उदाहरण। ये दोनों एक ही बात करते हैं - एक धारा में बाइट्स की संख्या:

class StreamCount 
{ 
    private Stream str; 
    private int total = 0; 
    private byte[] buffer = new byte[1000]; 

    public Task<int> CountBytes(Stream str) 
    { 
     this.str = str; 

     var tcs = new TaskCompletionSource<int>(); 
     Action onComplete =() => tcs.SetResult(total); 
     str.BeginRead(this.buffer, 0, 1000, this.BeginReadCallback, onComplete); 

     return tcs.Task; 
    } 

    private void BeginReadCallback(IAsyncResult ar) 
    { 
     var bytesRead = str.EndRead(ar); 
     if (bytesRead == 0) 
     { 
      ((Action)ar.AsyncState)(); 
     } 
     else 
     { 
      total += bytesRead; 
      str.BeginRead(this.buffer, 0, 1000, this.BeginReadCallback, ar.AsyncState); 
     } 
    } 
} 

... और ...

public static async Task<int> CountBytes(Stream str) 
    { 
     var buffer = new byte[1000]; 
     var total = 0; 
     while (true) 
     { 
      int bytesRead = await str.ReadAsync(buffer, 0, 1000); 
      if (bytesRead == 0) 
      { 
       break; 
      } 
      total += bytesRead; 
     } 
     return total; 
    } 
मेरी आँखों के लिए

, async तरह से क्लीनर है, लेकिन है कि वहाँ ' जबकि (सच) 'लूप कि मेरा अशिक्षित मस्तिष्क मुझे बताता है कि एक अतिरिक्त थ्रेड, अधिक संसाधनों का उपयोग करने जा रहा है, और इसलिए दूसरे के साथ-साथ स्केल नहीं करेगा। लेकिन मुझे पूरा यकीन है कि गलत है। क्या वे वही काम कर रहे हैं?

उत्तर

7

मेरी आंखों के लिए, एसिंक रास्ता क्लीनर दिखता है, लेकिन वहां 'जबकि (सत्य)' लूप है कि मेरा अशिक्षित मस्तिष्क मुझे बताता है कि एक अतिरिक्त थ्रेड, अधिक संसाधनों का उपयोग करने जा रहा है, और इसलिए स्केल नहीं करेगा साथ ही साथ दूसरा।

नहीं, यह नहीं होगा। लूप केवल वास्तव में कोड चलाते समय थ्रेड का उपयोग करेगा ... जैसा कि यह आपके BeginRead कॉलबैक में होगा। await अभिव्यक्ति जो भी कॉलिंग कोड है, उस पर नियंत्रण वापस कर देगी, जिसने एक निरंतरता पंजीकृत की है जो विधि में सही स्थान पर वापस आती है (एक उपयुक्त थ्रेड में, सिंक्रनाइज़ेशन संदर्भ के आधार पर) और तब तक चलती रहती है जब तक कि यह अंत तक न हो जाए विधि का या await अभिव्यक्ति को हिट करता है। यह वही है जो आप चाहते हैं :)

दृश्यों के पीछे एसिंक/प्रतीक्षा कैसे काम करता है इसके बारे में अधिक जानने के लायक है - आप the MSDN page on it के साथ एक कूदते बिंदु के रूप में शुरू करना चाहेंगे।

+0

यह जानना अच्छा है! वास्तव में सहायक मैं एमएसडीएन पेज को पूरी तरह से पढ़ूंगा। मुझे लगता है कि प्रवाह आरेखों ने मुझे पहले डरा दिया, लेकिन मैं बहादुर हो जाऊंगा! :) [जब मैं कर सकता हूं स्वीकार करेंगे] – Barguast

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