2013-03-16 11 views
9

私は次の二つの方法タスクを取得して渡すメソッドを待つ必要がありますか?

public async Task<bool> DoSomething(CancellationToken.token) 
{ 
    //do something async 
} 

//overload with None token 
public /*async*/ Task<bool> DoSomething() 
{ 
    return /*await*/ DoSomething(CancellationToken.None); 
} 

は、第二の方法は、非同期でマークする必要がありますしている/キーワードを待ちますか?

答えて

12

それはする必要はありません - あなたは第二の方法でのawait /非同期を使用する場合は、この場合には、何も達成していない余分なオーバーヘッドを追加することがあります。

DoSomething(CancellationToken)の内部非同期作業はすでに適切な非同期処理を提供し、あなたのために既存のコンテキストに戻ってマーシャリングします。

asyncawaitは実際にはTaskの作成と作成を容易にする言語機能です。すでに返すためにTask完璧なを持っている場合は、新しいTaskにそれをアンラップし、再度ラップするために余分な言語サポートを使用する必要はありません。

Func<int, int> GetFunc() 
{ 
    Func<int, int> f = GetFunc(someParameter); 

あなたは

return f; 

や理由を言うべき「私はここでFUNCを返すことになって、そうしてみましょうよ:、リードの良い答えに追加し、それについてこのように考えるように

+0

は、その後、ちょうどリターンの前に私はいくつかのショートコードを書くことができます戻り型の不一致...この場合、あなたは何をお勧めしますか? Task.FromResultを使用しますか?それとも、この場合、非同期でラップを待っていますか? – labroo

+2

@labrooこの場合は、おそらく "Task.FromResult"を使用します。 – hazzik

11

return (int i) => f(i); 

私はあなたが前のことをしたいと思っています。あなたはすでにFunc<int, int>を手にしているので、返却してください。 funcを呼び出すfuncを作成しないでください。

あなたは

IEnumerable<int> GetSequence() 
{ 
    IEnumerable<int> sequence = GetSequence(someParameter); 

を持っていた場合、あなたは

return sequence; 

または

foreach(int item in sequence) yield return item; 

と思いますか?再び、私はあなたが前者をやることを願っています。あなたは手元にあるシーケンスを持っているので、古いシーケンスを列挙する新しいシーケンスを作るのに苦労するのはなぜですか?

同じタスクのために行きます。あなたが別のデリゲートと別のシーケンスをラップシーケンスをラップデリゲートを作ることができると同じように、あなたは別のタスクをラップ作業を行いますが、なぜでしょうか?それは単なる資源の無駄です。私は非同期の方法をマークし、返す前に待っていた場合は、非同期キーワードなし「(someCondition)falseを返す場合は」..はこれが不可能であるように、それは文句を言うので

+0

興味深いことに、ReSharperは、これらの2つの間違いのいずれかを行うコードを検出して(自動的に修正するように指示します)。私はそれがOPの事件を検出するかどうか分からない。 – Brian

+3

@ブライアン:面白い。後者の場合は間違いなくバグではありません。効果があるからです。最初に、結果のシーケンスがソースシーケンスと参照アイデンティティを持たないことを保証し、第2に、ソースシーケンスが読み込まれていない場合でも、第2のシーケンスが*読み込み専用であることを保証する。 –