2012-09-03 5 views
14

非同期:Task <>でasyncとawaitを使用する理由私は私がしたい通常の方法を持っている場合は

public int Foo(){} 

は、私はどうなる:

public Task<int> FooAsync(){ 
    return Task.Run(() => Foo()); 
} 

をなぜだろう:

public async Task<int> FooAsync(){ 
    return await Task.Run(() => Foo()); 
} 

私がすることを計画する方法をこれは次のとおりです:

FooAsync().ContinueWith((res) => {}); 

メソッドを停止せずに実行するだけですが、コールバックのようなものが起動されるようにしたいので、ContinueWithとします。しかし、2番目のバージョンでは、それを使用するポイントはありますか?私の理解で

答えて

14

あなたには、いくつかの非同期の内部呼び出しますが、それはないようにあなたが外観にそれをしたいと思いませんメソッドを書くとき、あなただけのasyncawaitを必要としています。言い換えれば、通常のシーケンシャルコードであるかのようにコードを書いたり読んだり、通常のシーケンシャルコードであるかのように例外を処理したり、通常のシーケンシャルコードであるかのように値を返したりすることです。コンパイラの責任は、ロジックを保持する必要なすべてのコールバックでそのコードを書き換えることです。

あなたのメソッドはとても簡単ですが、書き換えが必要ないと思いますが、タスクを返すことはできますが、それを消費する人は戻り値がawaitになる可能性があります。

+0

優秀な説明! – paulsm4

+0

ありがとう、@ paulsm4。私は、私が最近聞いたことを書き直していると言わなければならない、と私は思う、それはhttp://hanselminutes.com/327/everything-net-programmers-know-about-asynchronous-programming-is-wrongからだと思う。 100%は確実ではありません。私はまだ非同期機能に関する多くの経験がありませんでしたので、私は間違っている可能性があり、私はもっと学ぶことを喜んで、おそらく非同期はこの場合いくつかの利点を提供します。 –

+2

さらに、[同期メソッドの非同期ラッパーを公開する必要がありますか?](http://blogs.msdn.com/b/pfxteam/archive/2012/03/24/10287244.aspx)の回答あなたが同期メソッドを持っているならば、ほとんど常に "いいえ"です、そしてそれに同期メソッドシグネチャを与えます)。 –

5

のはなぜだろう:

public async Task<int> FooAsync() 
{ 
    return await Task.Run(() => Foo()); 
} 

あなたはいないだろう。あなたの以前のバージョンは、すでに待っているタスクを返します。この新しいバージョンは何も追加しません。

私はこれを使用する予定の方法は次のとおりです。

FooAsync().ContinueWith((res) => {}); 

は、私はこの方法だけで停止せずに実行したいが、私は、コールバックのようなものは、したがって、発射ContinueWithすることにしたいです。 。

asyncを使用して
void DoAsyncStuff() 
{ 
    FooAsync().ContinueWith((res) => { DoSomethingWithInt(res.Result) }); 
} 

、あなたはこのように同じコードを書くことができます:違いの出番があるのはあなたの例を少し肉付けしてみましょう

void async DoAsyncStuff() 
{ 
    int res = await FooAsync(); 
    DoSomethingWithInt(res); 
} 

結果は同じです。 awaitキーワードは、メソッドの残りの部分をFooAsyncが値を生成した後に再開するコンティニューに変換します。それはあなたの他のコードと似ていますが、読むのが簡単です。 *ほら*

+0

あなたの 'async'メソッドは本当に '返すことはできません。 'async'メソッドは、それらがイベントのハンドラになるときに戻るだけvoidでなければなりません。メソッドに戻り値がない場合、 'Task'を返します。それ以外は、まともな投稿です。 – Servy

+0

@Servy "非同期メソッドはイベントのハンドラになると返されるだけです。"それがここのケースですよね?この例では 'DoAsyncStuff'は何を返すべきですか?余計なコードを書かずにどこの値を取得しますか?また、非同期メソッドがTaskを返して、それを待たずにコンパイラの警告(CS4014)を受け取ると、迷惑です。私は最近、[その問題について尋ねました](http://stackoverflow.com/questions/14903887/warning-this-call-is-not-awaited-execution-of-the-current-method-continues)ここに。より良い回答があれば、そこに投稿できますか? – Mud

+0

'async'メソッドがvoidを返すとき、それは本質的に" fire and forget "メソッドになります。呼び出し元は、メソッドが実際に終了したときを知る方法がありません。 OPのコードからは、彼が望んでいることは分かりません。コンパイラの警告に関しては、あなたがリンクしたポストであなたに言ったように、あなたはほぼ確実に*それをしたくないからです。警告はあなたのデザインに欠陥があることを示す*正しく*表示されており、その確率はあなたが得ている行動を望んでいないということです。あなたはいくつかのエッジケースでその動作が必要なかもしれませんが、私は私の主張に立っています。 – Servy

関連する問題