2012-12-12 16 views
5

मैं सी # में नए async और await कीवर्ड देख रहा हूं और बस उनके लिए एक महसूस करने की कोशिश कर रहा हूं।फ़ाइलस्ट्रीम WriteAsync और भ्रम का इंतजार

मैं एमएसडीएन FileStream.WriteAsync()example देख रहा हूं, और मुझे यकीन नहीं था कि मुझे कुछ समझ आया है।

using System; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows; 
using System.Windows.Controls; 
using System.IO; 

namespace WpfApplication1 
{ 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
     } 

     private async void Button_Click(object sender, RoutedEventArgs e) 
     { 
      UnicodeEncoding uniencoding = new UnicodeEncoding(); 
      string filename = @"c:\Users\exampleuser\Documents\userinputlog.txt"; 

      byte[] result = uniencoding.GetBytes(UserInput.Text); 

      using (FileStream SourceStream = File.Open(filename, FileMode.OpenOrCreate)) 
      { 
       SourceStream.Seek(0, SeekOrigin.End); 
       await SourceStream.WriteAsync(result, 0, result.Length); 
      } 
     } 
    } 
} 

क्या मैं नहीं मिलता है await की नियुक्ति है:

उदाहरण इस प्रकार है। ऐसा लगता है कि आप आइटम नहीं ले सकते हैं जो WriteAsync() द्वारा लौटाया गया है क्योंकि यह हमेशा मुझे एक वाक्यविन्यास त्रुटि देता है। तो संकलन के लिए मैं इसे प्राप्त करने का एकमात्र तरीका कॉल के साथ await छोड़कर है।

लेकिन यदि आप ऐसा करते हैं, तो क्या यह कॉल समाप्त होने की प्रतीक्षा नहीं करता है? यह बहुत असीमित नहीं बनाता है ...

+0

'टास्क' आइटम "ले" से आपका क्या मतलब है? –

+0

@ जोन कुछ 'टास्क टी = SourceStream.WriteAsync (परिणाम, 0, परिणाम। लम्बाई);' और बाद में 'प्रतीक्षा करें;' – Andrew

+2

आप निश्चित रूप से ऐसा कर सकते हैं - आपको क्या लगता है कि आप ऐसा नहीं कर सकते हैं? –

उत्तर

13

मुझे संदेह है कि await क्या आपकी समझ के साथ समस्या है।

लेकिन यदि आप ऐसा करते हैं, तो क्या यह कॉल समाप्त होने की प्रतीक्षा नहीं करता है? यह यह बहुत अतुल्यकालिक नहीं है ...

जब आप await कुछ को "ब्लॉक अतुल्यकालिक रूप से" - जब अतुल्यकालिक आपरेशन पूरा कर लिया है अपने अतुल्यकालिक समारोह जारी रहेगा, लेकिन तत्काल कॉल तुरंत पूरी कर लेगा।

तो आपके मामले में, यूआई थ्रेड अनब्लॉक हो जाता है क्योंकि Button_Click रिटर्न होता है, लेकिन जब फ़ाइल लिखने का ऑपरेशन पूरा हो जाता है, तो await अभिव्यक्ति के अंत तक निष्पादन वापस आ जाएगा (अभी भी UI थ्रेड में) ... आप करेंगे फिर FileStream बंद करें और एसिंक्रोनस फ़ंक्शन को पूरा करें।

यह स्पष्ट होगा कि आपने await अभिव्यक्ति के बाद कुछ और किया था (उदाहरण के लिए यूआई अपडेट करना)। लेकिन हाँ, यह वास्तव में असीमित है - यह आपको कोड लिखने की अनुमति देता है जो तुल्यकालिक लगता है।

+0

तो मान लें कि मैंने 'प्रतीक्षा' के बाद 'doWork() 'कुछ विधि की है, विधि को नहीं कहा जाएगा लिखने के बाद तक पूरा हो गया है? – Andrew

+3

@ एंड्रयू: वास्तव में।लेकिन जब आपका एसिंक्रोनस फ़ंक्शन पूरा करने का इंतजार कर रहा था, तो यह * यूआई थ्रेड को पकड़ नहीं पाएगा। यह पिज्जा को ऑर्डर करने जैसा है - जब तक इसे डिलीवर नहीं किया जाता है तब तक आप * पिज्जा * नहीं खा सकते हैं, लेकिन आप इसके बजाय अन्य चीजें कर सकते हैं :) –

+0

मुझे लगता है कि यह समझ में आता है। धन्यवाद! – Andrew

1

प्रतीक्षा प्रतीक्षा करते समय वास्तव में अवरुद्ध नहीं होता है। क्या होता है कि संकलक प्रतीक्षा के बाद सभी कोडों की तथाकथित निरंतरता बनाने के लिए कुछ जटिल चीजें करता है और कार्य पूरा होने पर उस निरंतरता को निष्पादित करने के लिए कार्य करता है।

मूल रूप से Button_Click विधि के अंतिम लाइनों के लिए अनुवाद किया जाता है:

FileStream SourceStream = File.Open(filename, FileMode.OpenOrCreate); 
SourceStream.Seek(0, SeekOrigin.End); 
Task t = SourceStream.WriteAsync(result, 0, result.Length); 
t.ContinueWith(_ => SourceStream.Dispose()); 

बेशक, यह सरल है के रूप में इस और अधिक कुशल निष्पादित किया जाएगा यदि WriteAsync तुरंत पूरा करता है, उदाहरण के लिए।

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