私がそのようなメソッドでインターフェース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
戻り値の型を指定する必要がありますか(ルールが不要になるのに対して)。
おそらく、このMSDNの記事 非同期のプラクティス を読むとよいでしょう。
あなたは尋ねました:
残念ながら、
DatabaseFolderRepository
の実装ではデータベースと通信するために同期メソッドを使用していましたが、skydrive 1では多くのasync
とawait
を使用しています。
これは、サブセクションAsync All the Way
私がリンクしたMSDN記事の中で、あなたの状況に関連しているでしょう。
特に、通常、非同期コードでTask.WaitまたはTask.Resultを呼び出してブロックすることはお勧めできません。これは、アプリケーションのごく一部を変換し、それを同期APIでラップしてアプリケーションの残りの部分を変更から切り離す、非同期プログラミングに「足を踏み入れ」ているプログラマーにとって特に一般的な問題です。残念ながら、それらはデッドロックの問題に遭遇します。
非同期にする必要があるインターフェースが少なくとも1つあるため、YAGNIは逆になります。あなたはインターフェースを一貫させるために変更を加える必要があります。はい、それはあなたのために前により多くの努力を作成します。しかし、利点はデッドロックのリスクが少ないことです。それほど複雑でないデバッグ。さらに予測可能なブロッキング(実際に発生する必要がある場合)。
私はあなたの質問の核心に対処したと思うので、あなたが尋ねた他のいくつかの質問をスキップしています。コアに対処すれば、残りの質問は失敗します。この記事はかなり複雑で、あなたが提起した他のポイントに対処するだけでなく、追加の落とし穴を指摘しています。
非同期プログラミングは、コンセプト全体を受け入れて、それをそのまま使用しなければならないものの1つです。少しずつ「つま先をひっくり返す」ことを試みると、まっすぐにジャンプするよりもはるかに複雑になります。