web-dev-qa-db-ja.com

.NET 4.5の「await」で使用できる.NET 4.0の非同期メソッドの作成

.NET 4.0およびVS2010でC#を使用する.NETプロジェクトがあります。

私がしたいのは、.NET 4.5のユーザーがawaitキーワードを使用して非同期プログラミングを簡単に行えるように、ライブラリに非同期オーバーロードを追加することです。現在、オーバーロードされているメソッドは非同期ではありません。また、非同期メソッドを自分で使用するのではなく、新しいメソッドを作成して使用可能にするだけです。

.NET 4.0およびVS2010で非同期メソッドを作成することは可能ですか?可能であれば、.NET 4.0非同期メソッドはどのように見えるべきですか?

VS2010を使用しているため、「async」キーワードにアクセスできないため、.NET 4.0でその動作をエミュレートするには何が必要ですか?たとえば、特定の型を返す必要があり、メソッド内でコードが発生して、呼び出している現在の非同期コードを非同期に発生させる必要がありますか?

41

他の人が述べたように、あなたはメソッドがTaskまたはTask<TResult>を返すことから始めます。これは、.NET 4.5での結果をawaitするのに十分です。

メソッドを将来の非同期コードにできるだけ適合させるには、 タスクベースの非同期パターンドキュメント (利用可能 MSDN )のガイドラインに従ってください。キャンセルをサポートするための命名規則とパラメーターの推奨事項を提供します。

メソッドの実装には、いくつかの選択肢があります。

32
Stephen Cleary

これを行う最も簡単な方法は、TaskまたはTask<T>を返すことです。それで十分でしょう。

ただし、これはメソッドが実際に非同期で実行される場合にのみ意味があります。

また、AbcAsync( "Async"サフィックス)のような名前を付ける通常のパターンに従うことをお勧めします。呼び出し元は、C#5で作成された非同期メソッドとの違いに気付かないでしょう(何もないため)。

ヒント:メソッドに非同期を追加するだけでは何も起こりません。メソッドは順番に実行され、完了したタスクを返します。メソッドにタスクを返すようにするには、特定の目的を果たす必要があります。通常、メソッドは本質的に非同期に実行されるため(Webサービス呼び出しやファイルIOなど)、これは行われます。

メソッドに計算のみが含まれ、IO(またはIOのブロックのみ))を行わない場合、通常は非同期にしない方がよいでしょう。非同期メソッドは常に別のスレッドで実行されるとは限りません。その最後の文に驚いた場合は、このトピックを少し掘り下げてみてください。

9
usr

何らかの方法で(スレッドまたは非同期で)完了するタスクを返す限り、非同期モデルをサポートします。

タスクを非同期に実行させることも別の話です。 asyncキーワードとAPIにアクセスできた場合は、既に提供されている非同期メソッドへの非同期呼び出しに基づいてメソッドを作成できます。ただし、この場合、非同期タスクを手動で作成する必要があります。

より良い方法があるかもしれませんが、私が見ることができる(そして使用した)最もエレガントな方法は、System.Threading.Tasks.TaskCompletionSourceタスクを構築するには、非同期メソッドのBegin/Endモデルを使用して、実行する必要があるものをすべて実行します。次に、結果を手元に置いたら、完了ソースを使用して、以前に構築したTaskインスタンスに結果を投稿します。

それは確かに非同期であり、ちょうど次のリリースのものよりも派手ではありません。

免責事項:私はこれに関する専門家に近い方法ではありません。いくつかの実験を行ったところです。

3
Ekin Koc