代码契约和异步

2024-03-17

将后置条件添加到返回的异步方法的推荐方法是什么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

这篇文章建议将每个方法实现为同步方法,对其进行收缩,然后将异步方法实现为简单的包装器。不幸的是,我不认为这是一个可行的解决方案(也许是由于我自己的误解):

  1. 异步方法虽然被假定为同步方法的包装器,但没有任何实际的代码契约,因此可以按照自己的意愿行事。
  2. 致力于异步的代码库不太可能为所有内容实现同步对应物。因此,实施新方法包括await因此,其他异步方法上的 s 被强制为异步。这些方法本质上是异步的,不能轻易转换为同步。它们不仅仅是包装纸。

即使我们通过说我们可以使用来使后一点无效.Result or .Wait()代替await(这实际上会导致一些SyncContexts 死锁,并且无论如何都必须在异步方法中重写),我仍然相信第一点。

是否有任何替代想法,或者我是否遗漏了关于代码契约和 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(使用前将#替换为@)

代码契约和异步 的相关文章

  • 检查列表是否包含另一个列表。 C#

    编辑 只是说 ContainsAllItem 中的注释解释得最好 很抱歉问这个问题 我知道以前有人问过这个问题 但我只是不明白 好的 所以我想检查一个列表是否包含另一个列表中的所有项目WITHOUT重叠 以及根据类字符串 名称变量 称为项目
  • 为什么假设 send 可能返回的数据少于在阻塞套接字上传输的请求数据?

    在流套接字上发送数据的标准方法始终是调用 send 并写入一大块数据 检查返回值以查看是否发送了所有数据 然后再次调用 send 直到整个消息被接受 例如 这是一个常见方案的简单示例 int send all int sock unsign
  • 如何将字节块读入结构体

    我有一个需要处理的资源文件 它包含一组文件 首先 资源文件列出了其中包含的所有文件 以及一些其他数据 例如在此结构中 struct FileEntry byte Value1 char Filename 12 byte Value2 byt
  • C 中的模仿函数重写

    具体来说 函数重写能够调用基本重写方法 这有两部分 一个是预编译的库代码 1 另一个是库的用户代码 2 我在这里实现了一个尽可能最小的经典 Person 和 Employee 示例 非常感谢了解 OOP 概念的铁杆 C 开发人员的回应 我正
  • 使用反射获取基类的受保护属性值

    I would like to know if it is possible to access the value of the ConfigurationId property which is located in the base
  • 抽象类或接口。哪种方式是正确的?

    有两种方法可以选择抽象类或接口 微软解决方案和Oracle解决方案 微软 设计指南 请使用抽象 在 Visual Basic 中为 MustInherit 类而不是接口来将协定与实现分离 http msdn microsoft com en
  • 如何使用泛型类型的 DataContractSerializer 编写自定义序列化器?

    我想编写一个自定义序列化器 用于将会话状态存储到Azure 缓存 预览版 这意味着这个自定义序列化器必须实现IDataCacheObjectSerializer 如果我错了 请告诉我 我需要编写这个自定义序列化程序的原因是我需要序列化一些包
  • 指示泛型返回动态类型的对象

    这个问题是我原来问题的后续问题here https stackoverflow com questions 2541184 using a type object to create a generic 假设我有以下泛型类 简化 class
  • 线程安全的 C++ 堆栈

    我是 C 新手 正在编写一个多线程应用程序 不同的编写者将对象推入堆栈 读者将它们从堆栈中拉出 或至少将指针推入对象 C 中是否有任何内置结构可以在不添加锁定代码等的情况下处理此问题 如果没有 那么 Boost 库呢 EDIT 你好 感谢您
  • 不要声明只读可变引用类型 - 为什么不呢?

    我一直在阅读这个问题 https stackoverflow com questions 2274412 immutable readonly reference types fxcop violation do not declare r
  • 从包含大量文件的目录中检索文件

    我的目录包含近 14 000 000 个 wav 格式的音频样本 所有普通存储 没有子目录 我想循环浏览文件 但是当我使用DirectoryInfo GetFiles 在该文件夹上 整个应用程序冻结了几分钟 可以用另一种方式完成吗 也许读取
  • `cosf`、`sinf` 等不在 `std` 中 [重复]

    这个问题在这里已经有答案了 根据这里的讨论 我有报告了一个错误 https bugs launchpad net ubuntu source gcc 8 bug 1831385给 Ubuntu 开发者 编译以下示例 C 程序时 includ
  • asp.net c# 防止在从服务器端代码更改索引时触发 selectedindexchanged 事件

    我在同一个 aspx 页面上有两个下拉列表控件
  • 在 .NET 中记录 StackOverflowException

    最近 我的 NET 应用程序 asp net 网站 中出现了堆栈溢出异常 我之所以知道该异常是因为它出现在我的 EventLog 中 我知道 StackOverflow 异常无法被捕获或处理 但是有没有办法在它杀死您的应用程序之前记录它 我
  • 将 bignum 类型结构转换为人类可读字符串的有效方法是什么?

    我有一点问题 为了增长我的 C 知识 我决定尝试实现一个基本的 bigint 库 bigint 结构的核心将是一个 32 位整数数组 选择它们是因为它们适合寄存器 这将允许我在数字之间进行操作 这些操作将在 64 位整数中溢出 这也将适合寄
  • 为什么C语言中可以使用多个分号?

    在 C 中我可以执行以下操作 int main printf HELLO WORLD 它有效 这是为什么 我个人的想法 分号是一个 NO OPERATION 来自维基百科 指示符 拥有一大串分号与拥有一个分号并告诉 C 语句已结束具有相同的
  • 如何将 CSV 文件读入 .NET 数据表

    如何将 CSV 文件加载到System Data DataTable 根据CSV文件创建数据表 常规 ADO net 功能是否允许这样做 我一直在使用OleDb提供者 但是 如果您正在读取具有数值的行 但希望将它们视为文本 则会出现问题 但
  • 在何处将 CFLAG(例如 -std=gnu99)添加到 (Eclipse CDT) 自动工具项目中

    我有一个简单的 Autotools C 项目 不是 C 其框架是由 Eclipse CDT Juno 为我创建的 CFLAG 通过检查 似乎是 g O2 我希望所有生成的 make 文件也具有 std gnu99附加到 CFLAG 因为我使
  • 创建带有部分的选项卡式侧边栏 WPF

    我正在尝试创建一个带有部分的选项卡式侧边栏 如 WPF 中的以下内容 我考虑过几种方法 但是有没有更简单 更优雅的方法呢 方法一 列表框 Using a ListBox并将 SelectedItem 绑定到右侧内容控件所绑定的值 为了区分标
  • 如何从函数返回矩阵(二维数组)? (C)

    我创建了一个生成宾果板的函数 我想返回宾果板 正如我没想到的那样 它不起作用 这是函数 int generateBoard int board N M i j fillNum Boolean exists True initilize se

随机推荐

  • Nginx 未运行且没有错误消息

    我正在尝试启动我的 nginx 服务器 当我输入 gt etc init d nginx start 时 出现一条消息 正在启动 nginx 然后什么也没有发生 没有错误消息 当我检查 nginx 的状态时 我发现它没有运行 这是我的 et
  • 程序在 execvp( command.argv[0], command.argv) 之后停止

    我正在编写一个小型 shell 程序 它接受命令并执行它 如果用户输入无效命令 if 语句将返回 1 如果命令正确 则执行该命令 但是一旦执行该命令 程序就会结束 我做错了什么 不执行后面的代码行 我已经使用 ls 和 cat 命令测试了
  • 使用公式内现有单元格的值

    我正在使用 Excel 2010 中的 相机 功能 我的目标是有一个单元格 其中有一个我可以手动输入的日期 并且在其下方 公式将获得更新的值 该值代表另一个 Excel 文件中的工作表名称 并向我显示更新的屏幕截图 例如 细胞A1 has
  • 如何隐藏 VS Code 中的状态栏?

    如何隐藏 Visual Studio Code 中的状态栏 应该可以隐藏状态栏 有什么办法可以隐藏它吗 在 查看 菜单中 我找不到隐藏它的选项 View gt Appearance gt Show Status Bar Screenshot
  • subprocess.wait() 不等待 Popen 进程完成(使用线程时)?

    我在使用时遇到一些问题subprocess Popen 使用线程从我的 python 脚本生成同一应用程序的多个实例 使它们同时运行 在每个线程中 我使用以下命令运行应用程序popen 调用 然后我通过调用等待它完成wait 问题似乎在于w
  • 解析两个 XML 标签之间的值

    我知道以前有人问过这个问题 但我似乎找不到合适的解决方案 所以我会说明问题 我有一个类似于 XML 文件的字符串 它不是 XML 字符串 但有开始和结束标记 所有信息都位于一行中 例如
  • 电子邮件客户端无法验证带有 bouncycastle 签名的附件和图像的电子邮件

    我有一个邮件编辑器构建哑剧消息并使用邮件签名服务 签名是在sign and 构建签名生成器 方法 收到邮件后 邮件客户端检测到签名 但抱怨邮件可能已被篡改 邮件客户端能够显示证书 它显示所有证书 包括 CA 因此 要么基于 Bouncyca
  • 让 Rscript 从 stdin 读取或获取输入

    我了解了如何让 Rscript 在给定文件名作为参数时执行我想要的操作 例如如果我的 Rscript 被调用script并包含 usr bin Rscript path lt commandArgs 1 writeLines readLin
  • Doctrine Querybuilder ORDER BY 子句不在 SELECT 列表中

    我有以下查询生成器 queryBuilder this gt createQueryBuilder recipient gt leftJoin recipient message message gt orderBy message dat
  • $.post 仅适用于警报 [关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 当我调用带有警报的功能时 该功能运行良好 function post var cvs client nbr val var cs cs va
  • Ruby on Rails:在单个数据库单元中保存多个值

    如何在 Ruby on Rails 应用程序中的单个单元格记录中保存多个值 如果我有一个名为Exp列名为 Education Experience and Skill 如果我希望用户在单行中存储多个值 例如 教育机构或技能 最佳实践是什么
  • 崩溃报告显示在 App Store Connect 中,但不显示在 Xcode Organizer 中

    我们已将应用程序上传到 TestFlight 进行 Beta 测试 当应用程序在测试人员的设备上崩溃时 崩溃会按预期显示在 App Store Connect 中 但不会显示在 Xcode Organizer 中 管理器中的崩溃选项卡显示了
  • PagedListAdapter.submitList() 更新现有项目时行为异常

    本主题的小故事 应用程序只是在确认后通过对话框更新单击的行的值 在房间数据库上使用分页方案 当添加或删除项目时 会获取最新的数据集并将其传递给submitList方法 然后所有更改都会被看到并且运行良好 问题从这里开始 如果更新了现有项目
  • 设置 AssemblyInfo.cs 的默认值

    更改创建 AssemblyInfo cs 的默认值的最佳方法是什么 例如我不想要 AssemblyCompany 和 AssemblyCopyright 中的 Microsoft 位 assembly AssemblyCompany Mic
  • 使用Python unicode的特殊字符问题

    usr bin env python coding utf 8 def splitParagraphIntoSentences paragraph break a paragraph into sentences and return a
  • Python ctypes 参数与 DLL - 指向双精度数组的指针

    我是一名使用 Python 中的 ctypes 的新手编码人员 并尝试使用用 C 编写的 DLL 中的函数 我在 SO 上发现了很多与我类似的问题 但没有任何答案可以回答此类难题 我已经很好地加载了 DLL 但是我需要调用的函数之一需要一个
  • marionette.js 布局/区域结构和渲染方法示例

    我正在尝试使用 marionette js 作为我的主干应用程序 但我对如何组织布局 区域并渲染它们感到有点困惑 我正在寻找一个具有嵌套布局和区域的示例应用程序 以便我可以更好地理解 有什么建议吗 看看这个小提琴 http jsfiddle
  • Guid.NewGuid() 返回重复项?

    我们有一个应用程序可以为我们的一项服务生成模拟数据以用于测试目的 每个数据项都有一个唯一的 Guid 然而 当我们对模拟器进行一些小的代码更改后运行测试时 它生成的所有对象都具有相同的 Guid 创建了一个数据对象 然后是一个 for 循环
  • Cocoa 应用程序最简单的 Markdown 实现是什么?

    我正在用 Objective C 编写一个 Cocoa 应用程序 并且我希望能够合并 Markdown 用户以 Markdown 语法输入文本 单击 导出 按钮 程序将输出 XHTML 文件 不过 似乎有很多选择 我可以使用其中之一C C
  • 代码契约和异步

    将后置条件添加到返回的异步方法的推荐方法是什么Task