2012-12-12 7 views
5

私は新しいasyncawaitのキーワードをC#で探しています。FileStream WriteAsyncと混乱を待ちます

私はMSDN FileStream.WriteAsync()exampleを見ていて、何かを理解しているかどうかはわかりませんでした。私は何を得ることはありませんがawaitの配置である

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); 
      } 
     } 
    } 
} 

次のように

例があります。 WriteAsync()によって返されるTaskの項目を受け取ることができないと思われるので、これは常に私に構文エラーを与えるためです。だから私はこれをコンパイルすることができる唯一の方法は、awaitを呼び出すことです。

これを行うと、通話が終了するのを待つことはありませんか?これはそれほど非同期ではありません...

+0

「タスク」アイテムを「取る」とはどういう意味ですか? –

+0

@Jon「タスクt = SourceStream.WriteAsync(結果、0、result.Length);」のようなものです。後で 'await t;'を実行します – Andrew

+2

あなたは間違いなくそれを行うことができます。 –

答えて

13

私は問題が何であるか理解していると思っています。await

これを行うと、通話が終了するのを待たないのですか?これは...それは非常に非同期ではない可能

とき await何か、あなたの「非同期ブロック」 - 非同期操作が完了したときに、あなたの非同期関数を続けますが、即時の呼び出しがすぐに完了します。

Button_Clickが返されるためUIスレッドはブロックされませんが、ファイル書き込み操作が完了すると、実行は(UIスレッドのままで)await式の末尾に戻ります。 FileStreamを閉じて非同期機能を完了します。

awaitの表現(UIの更新など)の後に何が起こったのかがはっきりしています。しかし、はい、実際には非同期です - と思われるコードを書き込むことができます。と同期しています。

+0

'' await'の後に 'doWork()'メソッドをいくつか行ったとしましょう。メソッドは呼び出されません書き込みが完了した後まで – Andrew

+3

@Andrew:確かに。しかし、あなたの非同期関数が完了するのを待っていた間に、* UIスレッドを保持していませんでした。それはピザを注文するようなものです。ピザが届くまでピザを食べることはできませんが、代わりに他のことをすることができます:) –

+0

私はそれが理にかなっていると思います。ありがとう! – Andrew

1

待っている間、待ち時間は実際にはブロックされません。何が起こるかは、コンパイラが待ってから、すべてのコードの継続と呼ばれるいくつかの複雑な処理を行い、完了時にその継続を実行するように指示します。

基本的Button_Clickメソッドの最後の行はに変換され:WriteAsyncが直ちに終了した場合、これは、例えば、より効率的に実行されるように、これは簡略化され、もちろん

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