私は、複数のクライアントオブジェクトがインターフェースを介して特定の機能を実装することが期待されているシステムに取り組んでいます。そして、その機能を継続と非同期的に実行することを望みます。すべてのクライアントオブジェクトができるだけ早くこの機能を完了するようにしてください。 C# "5.0"のSP1用のVisual Studio非同期CTP更新を使用しています。
抽象クラスの子オブジェクトで非同期動作を強制するための推奨される方法は何ですか(下記参照)。私は(明らかに)仮想メソッドアプローチを使って '非同期'メソッドの使用を強制することはできません。 'Task'の返品タイプのみが必要です。つまり、子オブジェクトでは非同期動作をまったく要求しないようにする必要がありますか?その場合、戻り型は単に 'void'であるべきですか?
パブリックインタフェースは、今のところシステム設計の不幸な結果ですが、それは別の問題です。明らかに、 'BaseFoo'を迂回し、単に 'IFoo'インターフェースを実装するだけで、誰にも非同期であることを強制することはできませんでした。
これがコードです:
public interface IFoo
{
void Bar(); //NOTE: Cannot use 'async' on methods without bodies.
}
public abstract class BaseFoo : IFoo
{
public async void Bar()
{
await OnBar(); //QUESTION: What is the right "async delegation" pattern?
}
protected virtual async Task OnBar()
{
await TaskEx.Yield();
}
}
public class RealFoo : BaseFoo //NOTE: May be implemented by 3rd party
{
protected override async Task OnBar()
{
//CLIENT: Do work, potentially awaiting async calls
await TaskEx.Yield(); //SECONDARY QUESTION: Is there a way to avoid this if there are no 'awaits' in the client's work?
}
}
メソッドがを使って実装されているかどうかasync/awaitかどうかは実装詳細方法はどうあるべきか振る舞う契約の詳細です。通常の方法で指定する必要があります。
あなたがメソッドを返すようにすると注意してくださいTaskまたはTask<T>それは非同期であることを意図していること、そしておそらく実装するのが難しいだろうことはより明白ですなしで非同期です。
一方、(テスト目的などの)実装がある場合は、await式は決して不完全である、なぜあなたは誰かにnoで非同期メソッドを書くことを強制したいと思うでしょうawaitとにかく電話?あなたは期待して実装はIOバウンドであるべきですが、実装がハードコードされたデータなどを使いたいという特別な場合があるでしょう。
基本的にはメソッドのドキュメントでこれを処理する必要があります - 実装者がそれを読むことを信頼できないのであれば、とにかくチャンスはありません:(
Jonの答えに加えて、あなたがフォローしているならタスクベースの非同期パターンそれからあなたのメソッド名は接尾辞を付けるべきですAsyncこれは、それが非同期メソッドであることを自己証明しています。
あなたがインターフェースを実装しているなら
public interface IFoo
{
Task BarAsync();
}
これがで実装されるべきであることは明らかであるべきですasyncキーワード。
Task戻り型ではなくvoidいつでもどこでも -void非同期メソッドを使ってイベントハンドラを実装できるようにするためです。非同期メソッドが完了するのを待つことができると便利なことがよくあります。Taskそれは簡単です。 - Jon Skeet