2013-06-01 11 views
9

私は待っていたいメソッドを持っていますが、私はこの呼び出しメソッドを呼び出すことができ、それを待っていると考えてドミノ効果を引き起こしたくありません。この親メソッドで非同期修飾子を使用せずに非同期メソッドを待つことはできますか?

public bool Save(string data) 
{ 
    int rowsAffected = await UpdateDataAsync(data); 
    return rowsAffected > 0; 
} 

私が呼んでいる:私はSave()用メソッド署名に「非同期」を配置する必要があり、その後、私ができるので

public Task<int> UpdateDataAsync() 
{ 
    return Task.Run(() => 
    { 
    return Data.Update(); //return an integer of rowsAffected 
    } 
} 

これは動作しませんたとえば、私はこの方法を持っています返信bool私はそれをTask<bool>にしなければならないが、私はSave()メソッドを待っている誰も望んでいない。

私はaswaのようなコードの実行を中断することができますか、何らかの形で非同期修飾子なしでこのコードを待っていますか?

+2

あなたが私のスレッドをブロックした 'Save'メソッドにアクセスできるようにして、' Task'で呼び出しをラップするように強制すると、かなり迷惑になります。 。ただ言って。 –

答えて

7

この親メソッドで非同期修飾子を使用しないで非同期メソッドを待機させる方法はありますか?

これは、「どのようにC#を使用してアプリケーションを作成できますか?ただし、どのような種類の.NETランタイムにも依存しませんか?

短い回答:しないでください。

実際には、自然に同期する方法(Update)を使用して、スレッドプールスレッド(UpdateDataAsync)でスレッドを実行して非同期に見えるようにしてから、ブロックしたい非同期メソッドを同期して表示させます(Save)。深刻な赤旗。

Stephen Toubの有名なブログ記事should I expose asynchronous wrappers for my synchronous methodsshould I expose synchronous wrappers for my asynchronous methodsを慎重に検討することをおすすめします。両方の質問に対する答えは「いいえ」ですが、実際に行う必要がある場合はStephen Toubがそれを行うためのいくつかのオプションを説明しています。

「本当にする必要がある」ということは、アプリケーションレベルで予約する必要があります。これらのメソッド(UpdateUpdateDataAsync、およびSave)は、アプリケーションの異なるレイヤー(たとえば、データ/データサービス/ビューモデル)にあると仮定します。データ/データサービス層は、同期/非同期変換を行ってはいけません。ビューモデル(アプリケーション固有)レベルは、そのような変換を行う言い訳がある唯一のものであり、最後の手段としてそうするべきです。

+0

データベースに(Asyncドライバを使って)ものを入れたテストケースを書いてすぐにそれを読み返すのはどうでしょう?ちょうど、同期プログラミングの正当なユースケースがあります。 – Hypershadsy

+0

@Hypershadsy:なぜ非同期に行うことができませんでしたか? –

+0

非同期テストケースを記述できますか? – Hypershadsy

3

編集:この回答はTask.Runが追加される前です。その余分な文脈では、シナリオは "それをしないでください"と表現するのが最良です。


あなたは.Resultにアクセスしたり、.Wait()を使用しますが、タスクが最初に実装されている方法を知っておく必要がありますすることができます。特に、同期コンテキストを使用するかどうかを知る必要があります。これが重要な理由は、いくつかの同期コンテキストではを完全に(たとえば、MVCの同期コンテキストはコントローラのアクションメソッドから離れる必要がある)を終了する呼び出しコンテキストが必要なため、これを行うとすぐにデッドロックする可能性があるからです。

これを防ぐのは難しいですが、場合によっては、常に.Wait()を呼び出して明示的にタイムアウトを指定する必要があります。

+0

ありがとう、私はTask.Runを使用しています - 私は2番目の方法を表示するために私の質問を更新しました – Neal

+0

@編集して、私はちょうど "それをしないでください"と言うだろう - あなたは何も理由なしにスレッドを追加しています。待機しているスレッド上で作業を行うこともできます。 –

+2

@Neal:Marcは絶対に正しいです。本質的にあなたがここでやっていることは、あなたの代わりに待っている人を雇って、あなたのために待っている仕事が終わるまで待つことです。あなたは実生活でそれをする人を雇うことはありませんので、ここではしないでください。タスクを実行するために同期的に待機する必要がある場合は、そのようにしてください。あなたが待っている間に仕事を続けたいなら、それを待つ。 –

関連する問題