違い

2016-05-20 4 views
1

非同期方法でそれを実行するための最良の形で何違い

public void MyMethod() 
{ 
    // do some stuff 
} 

public Task MyMethodAsync() 
{ 
    //run MyMethod asynchronously 
} 

...のは、私はこのような2つのメソッドを持っていると仮定しましょうか?この

public Task MyMethodAsync() 
{ 
    return Task.Run(() => MyMethod()); 
} 

またはこのようなよう

public async Task MyMethodAsync() 
{ 
    await Task.Run(() => MyMethod()); 
} 
+2

これは実際には非同期ではなく、別のスレッドで実行しているだけです。あなたが待っている非同期メソッドで実際のIOバインドされた作業をしていれば、それを同期化することができます。 – juharr

+0

'Async'メソッドをそのまま使用して、消費者が望むならそれを待たせる。他のものを守っているだけの砂糖です。 – Jonesopolis

+1

私はMyMethodAsyncをまったく作っておらず、呼び出し側に 'Task.Run(()=> myClass.MyMethod());'呼び出しをさせてください。 「[fake async](http://blog.stephencleary.com/2013/10/taskrun-etiquette-and-proper-usage.html)」メソッドを作成するのは良い方法ではありません。 –

答えて

3

Task.Runを使用する場合は、いつでもStephen Cleary's tutorialを読む必要があります。

短い答え:Task.Runを使用して、偽の非同期メソッドを作成しないでください。あなたのコードが本当に非同期でない場合は、呼び出し元にスレッドを使用してコードを呼び出す必要があるかどうかを決定させてください。

+0

ありがとうございました。 – Jedi31

1

他の方法で行ってください。内部タスクを非同期として構築し、非同期メソッドを使用できないすべての呼び出し元に非同期メソッドを内部的に使用させ、待機させます。

public void MyMethod() 
{ 
    MyMethodAsync().Wait(); 
} 

public async Task MyMethodAsync() 
{ 
    // do some stuff 
} 

どちらの方法も真に非同期ではありません。 Asyncは、バックグラウンドで何かを実行することではなく、タスクライブラリ(または並列拡張、スレッドなど)の領域です。非同期は、何もしていないときに複数のものに対して単一のスレッドを再利用できるということです。これにより、スケーラビリティが向上します。擬似非同期メソッドを作ることは、同じスレッドを再利用するのではなく、新しいスレッドを使用しているという事実を隠しているだけで、システムをスケーラブルにすることができません。

これを行うには、真の非同期プロセスを内側から書き出す必要があります。すべて(または時間のかかる部分)は、そのような非同期メソッドに依存する必要があります。たとえば、呼び出しが返されるのを待つ間にスレッドが基本的にアイドル状態になるSOAP呼び出しを行うか、データベース呼び出し、またはファイルI/Oを実行します。非同期では、スレッドがただ単にアイドル状態になるのではなく、他の何かを行うのに便利です。

+1

明らかにasyncが実際に何であるかについて断りのない人からdownvoted。しかたがない。 –

+0

私はあなたが言っていることを理解していました...私はこの方法を実装するか分かりませんが、私は理解しました...;) – Jedi31

+0

もし私が1つを供給しなければならないなら、それはネイティブ非同期メソッドの同期バージョンを実装する方法です。 – moswald

1

最初の方法の場合は、別のスレッドでタスクを実行するだけでもよいでしょう。新しいプロセスを開始するためにスレッドが終了するのを明確に待っていないので、実際には非同期ではありません。これを呼び出すと、タスクが完了する前に続行されます。

public Task MyMethodAsync() 
{ 
    return Task.Run(() => MyMethod()); 
} 

第2のバージョンを見ると、タスクが完了するのを待っているので、現在のスレッドを保持せずに何かできることがあります。

public async Task MyMethodAsync() 
{ 
    await Task.Run(() => MyMethod()); 
    DoMoreWork(); 
    //Do something following the completion of the task 
    //without binding up the calling thread, but actually complete it on that thread. 
}