2016-04-08 10 views
5

タスクを待っているメソッドがあるとします。このメソッドはTaskも返します。たとえば:タスクが条件付きで実行される場合、非同期メソッドはどうすべきですか?

public async virtual Task Save(String path) 
{ 
    if (NewWords.Any()) 
    { 
     await FileManager.WriteDictionary(path, NewWords, true); 
    } 
    else await Task.Run(() => { }); 
} 

はここでは必要

else await Task.Run(() => { }); 

ですか私はそれを残して自由のですか?それが存在するかどうかの違いはありますか?多分私はこれを取るべき他のアプローチがありますか?

+1

なぜコードを挿入したか教えてください。それは必要ではなく、あなたが何かを誤解しなければならないという証拠です。それが何であるかを知る必要があります。 – usr

+1

それは必要ではなく、また有害です。 – IllidanS4

+0

DONT USE 'Task.Run'を実装する! http://blog.stephencleary.com/2013/11/taskrun-etiquette-examples-dont-use.html – Aron

答えて

4

何もしないようにスレッドをスピンアップしていて、何もしないで終了するまで待っているので、それは不必要なものより悪いです。

何もしない最も簡単な方法は何もしないことです。 async方法において、この方法は、まだTaskに戻ってきただろうが、それTaskはすでに完成されますので、何かawaitがアップし、さらにそれをINGのは、まっすぐそれを行う必要がある次の事になります。また、(

public async virtual Task Save(String path) 
{ 
    if (NewWords.Any()) 
    { 
     await FileManager.WriteDictionary(path, NewWords, true); 
    } 
} 

大文字と小文字の区別がある場合は、SaveAsyncWriteDictionaryAsyncとなります)。 ない場合asyncを使用しては(とそこここにする必要はませんが、私はそれが一例だ理解)Task.CompletedTaskを使用します。

public virtual Task Save(String path) 
{ 
    if (NewWords.Any()) 
    { 
     return FileManager.WriteDictionary(path, NewWords, true); 
    } 
    return Task.CompletedTask; 
} 

あなたが4.6より前のフレームワークに対してコーディングされているため、その後、CompletedTaskが使用できない場合Task.Delay(0)Delay特別な場合、キャッシュされた完了したタスクを返す値0として有用である(実際には、同じ1そのCompletedTaskリターン):

public virtual Task Save(String path) 
{ 
    if (NewWords.Any()) 
    { 
     return FileManager.WriteDictionary(path, NewWords, true); 
    } 
    return Task.Delay(0); 
} 

しかし、4.6の方法は、あなたのINTENにとして明確ですこれは、実装の癖に依存するよりむしろ。

+0

説明のおかげで、これで私はこれをきれいにするのに役立ちました。私はいくつかのコードパスで何も返さないようにコンパイラを困惑させました(このタスクはvoidを返すバックグラウンド操作の結果であることに気付いていますが)。私はコンパイラがそれを一意に扱うと思うのですが、それは無効なのでしょうか? –

+0

かなり。 'async'のポイントは、等価な同期メソッドを書くのと同じように、複雑なシーケンスの待ちタスクを他のタスクに返すメソッドを書くことです。したがって、何もしない同期メソッドは空でも(ブランチでも空でも)、完了したタスクを返すだけの 'async'もできます。実際に何が起きるかは、ステートマシンが作成され、 'yield'が' MoveNext() 'に変わるのと似ているので、これは' MoveNext() 'が最初に一度呼び出された後、 'await'ed returns ... –

+0

...' await'にヒットしなかったパスをたどった場合、その 'MoveNext()'への最初の呼び出しは完了したことを示します。そのステートマシン(実際にあなたのメソッドが返すもの)を使用する 'Task'は、完成した状態になります。 'MoveNext()'は 'Task'が完了する前に起こります(実際に' await'がすべて完了したタスクにヒットし、実際に待つ必要がない場合)。 –

5

これは必ずしも必要ではありません。 は少なくとも1つがawaitの場合にのみ必要です。メソッド内のすべては、awaitを除いて同期して実行され、後には何が実行されます。

関連する問題