インターフェースと非同期の設計


9

IFolderRepositoryそのようなメソッドを持つインターフェースを作成したとしましょう:

IEnumerable<Folder> GetAllFolders();
Folder GetFolderWithId(int id);
void AddFolder(Folder newFolder);
void ModifyFolder(Folder folderToModify, Folder folderAfterModification);
void RemoveFolder(Folder folderToRemove);

と私は実装DatabaseFolderRepositoryして言ってみましょうCacheFolderRepositoryDecorator。ここで「数百行後」にSkyDriveフォルダーの機能を追加したいので、追加しSkyDriveFolderRepositoryます。残念ながら、DatabaseFolderRepository実装はデータベースと通信するために同期メソッドを使用していましたが、skydrive 1では多くのasyncおよびを使用していますawait。そのような場合はどうしますか?voidメソッドで非同期とマークされている場合は、解決策ではありません(例外処理が必要)。インターフェースを変更して返す必要がありますTask<T>か?確かに上記の例では機能しますが、これらは2つのインターフェース実装クラスにすぎません。それとも、ほとんどのインターフェイスにTask戻り値の型があるべきですか(規則を必要としないので)。


あなたの質問とは無関係です(申し訳ありません)が、IFolderインターフェースがある場合、なぜFolderすべてのメソッドで具体的な実装()に依存するのですか?
Konrad Morawski、2014年

1
発信者は何を期待していますか?実装するAPIは、エラーコード、例外、コールバックなどに基づいていますか?変えられますか?
david.pfx 2014年

@KonradMorawskiそれはタイプミスでした-すみません。これは例外に基づいており、変更することはできません。
2014年

回答:


10

おそらく、非同期のプラクティスに関するこのMSDNの記事を読むとよいでしょう。

あなたは尋ねました:

残念ながら、DatabaseFolderRepository実装はデータベースと通信するために同期メソッドを使用していましたが、skydrive 1では多くのasyncおよびを使用していますawait

これは、Async All the Way私がリンクしたMSDN記事のサブセクションがあなたの状況に関連する場所です。

特に、非同期コードでTask.WaitまたはTask.Resultを呼び出してブロックすることは、通常はお勧めできません。これは、アプリケーションのごく一部を変換し、それを同期APIでラップしてアプリケーションの残りの部分を変更から切り離す、非同期プログラミングに「足を踏み入れ」ているプログラマーにとって特に一般的な問題です。残念ながら、それらはデッドロックの問題に遭遇します。

非同期にする必要があるインターフェースが少なくとも1つあるため、YAGNIは逆になります。あなたはしているあなたのインターフェイスが一致するよう変更を行うつもりが必要。はい、それはあなたのために前により多くの努力を作成します。しかし、利点はデッドロックのリスクが少ないことです。それほど複雑でないデバッグ。より予測可能なブロッキング(実際に発生する必要がある場合)。

私はあなたの質問の核心に対処したと思うので、あなたが尋ねた他のいくつかの質問をスキップしています。核心に対処すれば、残りの質問は消えます。この記事はかなり複雑で、あなたが提起した他のポイントに対処するだけでなく、追加の落とし穴を指摘しています。

非同期プログラミングは、コンセプト全体を受け入れて、それと一緒に進む必要があるものの1つです。少しずつ「つま先をひっくり返す」ことを試みると、まっすぐにジャンプするよりもはるかに複雑になります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.