質問: コード契約と非同期 What is the recommended way for adding postconditions to async methods which return `Task`? 私は次の提案を読んだ。 http://social.msdn Microsoft.com/Forums/hu-HU/async/thread/52fc521c-473e-4bb2-a666-6c97a4dd3a39 このポストでは、各メソッドを同期として実装し、それを縮小し、シンプルなラッパーとして非同期メソッドを実装することを提案しています。残念ながら、私はこれを実行可能な解決策とは考えていません(恐らく私自身の誤解によって): 1. asyncメソッドは、syncメソッドのラッパーと見なされていますが、実際のコード契約が残っていないため、望むとおりに行うことができます。 2. 非同期にコミットされたコードベースは、すべての同期相手を実装する可能性は低いです。その結果、他の非同期メソッドで `await` を含む新しいメソッドを実装すると、非同期に強制されます。これらのメソッドは、本質的に非同期であり、簡単に同期に変換することはできません。それらは単なるラッパーではありません。 `await` の代わりに `.Result` や `.Wait()`を使用することができ、 code> SyncContext をデッドロックにする必要があります。とにかくasyncメソッドで書き直す必要があります)、私はまだ最初の点について確信しています。 他のアイデアはありますか、コード契約やTPLについて私が見逃していることはありますか?
回答: 他の人が行ったように、これをAsyncチームに指摘しました。現在、契約と非同期は(ほぼ)相互排他的です。だから、マイクロソフトの少なくとも一部の人は、この問題を認識しているが、私は彼らがそれについて何をやろうとしているのか分からない。 同期メソッドのラッパーとして非同期メソッドを記述することはお勧めしません。実際、私は逆の傾向があります。 前提条件が働くことができます。私は最近それを試していない。前提条件を含む非同期メソッドの周りに小さなラッパーが必要な場合があります。 事後条件はかなり壊れています。 アサーションと仮定は正常に動作しますが、事後条件が壊れているため、静的チェッカーは実際には制限されています。 不変条件は、変更可能な状態がちょうど途切れることの多い非同期世界では、それほど意味を持たない。 (非同期で、OOPから機能的なスタイルに向かって優しくあなたを押しのけます)。 うまくいけばVS vNextで、契約は非同期対応のポストコンディションで更新されます。これにより、静的チェッカーが非同期メソッドのアサーションでよりうまく動作できるようになります。 その間に、あなたは仮定を書くことによって偽装 - 事後条件を持つことができます: ``` // Synchronous version for comparison. public static string Reverse(string s) { Contract.Requires(s != null); Contract.Ensures(Contract.Result() != null); return ...; } // First wrapper takes care of preconditions (synchronously). public static Task ReverseAsync(string s) { Contract.Requires(s != null); return ReverseWithPostconditionAsync(s); } // Second wrapper takes care of postconditions (asynchronously). private static async Task ReverseWithPostconditionAsync(string s) { var result = await ReverseImplAsync(s); //Check our "postcondition" Contract.Assume(result != null); return result; } private static async Task ReverseImplAsync(string s) { return ...; } ``` インタフェースや基底クラスの非同期メンバの事後条件を指定するなど、コード契約の用途はまったくできません。 個人的には、非同期コードで契約を完全に回避し、Microsoftが数カ月後に修正することを期待しています。