将后置条件添加到返回的异步方法的推荐方法是什么Task<T>
?
我已阅读以下建议:
http://social.msdn.microsoft.com/Forums/hu-HU/async/thread/52fc521c-473e-4bb2-a666-6c97a4dd3a39 http://social.msdn.microsoft.com/Forums/hu-HU/async/thread/52fc521c-473e-4bb2-a666-6c97a4dd3a39
这篇文章建议将每个方法实现为同步方法,对其进行收缩,然后将异步方法实现为简单的包装器。不幸的是,我不认为这是一个可行的解决方案(也许是由于我自己的误解):
- 异步方法虽然被假定为同步方法的包装器,但没有任何实际的代码契约,因此可以按照自己的意愿行事。
- 致力于异步的代码库不太可能为所有内容实现同步对应物。因此,实施新方法包括
await
因此,其他异步方法上的 s 被强制为异步。这些方法本质上是异步的,不能轻易转换为同步。它们不仅仅是包装纸。
即使我们通过说我们可以使用来使后一点无效.Result
or .Wait()
代替await
(这实际上会导致一些SyncContext
s 死锁,并且无论如何都必须在异步方法中重写),我仍然相信第一点。
是否有任何替代想法,或者我是否遗漏了关于代码契约和 TPL 的任何内容?
我已经向异步团队指出了这一点,正如其他人所做的那样。目前,合约和异步(几乎)是相互排斥的。所以,至少微软的一些人意识到了这个问题,但我不知道他们打算采取什么措施。
我不建议将异步方法编写为同步方法的包装器。事实上,我倾向于做相反的事情。
前提条件可以发挥作用。我最近没有尝试过;您可能需要一个包含先决条件的异步方法的小包装器。
后置条件几乎被破坏了。
断言和假设确实可以正常工作,但静态检查器确实受到限制,因为后置条件被破坏。
不变量在异步世界中没有多大意义,因为可变状态往往会造成阻碍。 (异步轻轻地将您从 OOP 推向函数式风格)。
希望在 VS vNext 中,合约将使用异步感知的后置条件进行更新,这也将使静态检查器能够更好地处理异步方法中的断言。
同时,您可以通过编写假设来获得假装后置条件:
// Synchronous version for comparison.
public static string Reverse(string s)
{
Contract.Requires(s != null);
Contract.Ensures(Contract.Result<string>() != null);
return ...;
}
// First wrapper takes care of preconditions (synchronously).
public static Task<string> ReverseAsync(string s)
{
Contract.Requires(s != null);
return ReverseWithPostconditionAsync(s);
}
// Second wrapper takes care of postconditions (asynchronously).
private static async Task<string> ReverseWithPostconditionAsync(string s)
{
var result = await ReverseImplAsync(s);
// Check our "postcondition"
Contract.Assume(result != null);
return result;
}
private static async Task<string> ReverseImplAsync(string s)
{
return ...;
}
代码契约的某些用法是不可能的 - 例如,在接口或基类的异步成员上指定后置条件。
就我个人而言,我刚刚在异步代码中完全避免了合约,希望微软能在几个月内修复它。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)