2012-12-12 58 views
5

我正在查看C#中的新關鍵字asyncawait,並試圖感受它們。FileStream WriteAsync並等待混淆

我正在查看MSDN 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()返回的Task項目,因爲這總是給我一個語法錯誤。因此,我可以編譯的唯一方法是讓await與電話通話。

但是,如果你這樣做,它不等待電話結束?這使得它不是非常異步...

+0

你是指「拿」「任務」項目是什麼意思? –

+0

@Jon類似於'Task t = SourceStream.WriteAsync(result,0,result.Length);'然後在做'await t;' – Andrew

+2

你可以這麼做 - 你認爲你不能做什麼? –

回答

13

我懷疑問題是你對await做什麼的理解。

但是,如果你這樣做,它不等待電話結束?這使得它不太異步...

當你await東西,你「塊異步」 - 你的異步函數會繼續當異步操作完成,但直接調用將立即完成。

因此,在你的情況下,UI線程變得暢通,因爲Button_Click返回,但是當文件寫入操作完成後,執行將返回(仍在UI線程中)到await表達式的末尾......然後關閉FileStream並完成異步功能。

如果您在await表達式(例如,更新UI)之後做了別的事情,那麼將會更清楚。但是,是的,它真的異步 - 它只是允許你編寫代碼,其中看起來同步。

+0

所以我們可以說我在'await'後面做了一些'doWork()'方法,該方法不會被調用直到寫完之後? – Andrew

+3

@Andrew:確實。但是當你的異步函數等待完成時,它*不會阻止UI線程。這就像訂購比薩餅 - 你不能吃比薩餅,直到它被交付,但你可以做其他事情:) –

+0

我認爲這是有道理的。謝謝! – Andrew

1

在等待時,await實際上並未阻塞。會發生什麼情況是,編譯器會執行一些複雜的工作,以便在await之後對所有代碼進行所謂的延續,並告訴任務在完成時執行該延續。

基本上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立即完成,例如這將被執行更有效的,這是簡化。