C# 有异步函数调用同步函数或同步函数调用异步函数

2024-02-21

我正在编写一个 C# .Net 4.5 库,用于执行常见的 sql 数据库操作(备份、恢复、执行脚本等)。我希望每个操作都具有同步和异步函数,因为控制台和 GUI 应用程序都将使用该库,但我不想到处重复代码。所以在我看来,我有两个选择:

  1. 编写在同步函数中完成工作的代码,然后将其包装在异步函数的任务中,如下所示:

    public void BackupDB(string server, string db)  
    {  
        // Do all of the work and long running operation here  
    }
    
    public async Task BackupDBAsync(string server, string db)  
    {  
        await Task.Factory.StartNew(() => BackupDB(server, db)).ConfigureAwait(false);  
    }
    
  2. 编写在异步函数中执行工作的代码,并使用 .Wait() 从同步函数调用它:

    public async Task BackupDBAsync(string server, string db)  
    {  
        // Do all of the work and long running operation here, asynchronously.  
    }
    
    public void BackupDB(string server, string db)  
    {  
        BackupDBAsync(server, db).Wait(); // Execution will wait here until async function finishes completely.  
    }
    

一种选择比另一种更好吗?这是最佳实践吗?或者还有其他(更好的)替代方案吗?

我知道使用 .Wait() 的一个警告是,异步函数中的所有等待语句都必须使用 .ConfigureAwait(false) 以避免死锁(正如这里所讨论的 https://stackoverflow.com/questions/9343594/how-to-call-asynchronous-method-from-synchronous-method-in-c),但由于我正在编写一个永远不需要访问 UI 或 WebContext 的库,所以我可以安全地这样做。

我还要指出的是,SQL 库通常还具有可以使用的同步和异步函数,因此,如果在同步函数中执行工作,我会调用它们的同步函数,如果在异步函数中执行工作,我会调用它们的同步函数。会调用他们的异步函数。

感谢您的想法/建议。

-- 编辑:我也发布了这个问题在 MSDN 论坛上 http://social.msdn.microsoft.com/Forums/en-US/async/thread/7bc69ba9-64b0-447e-b200-ca47c9fdce43尝试获得微软官方回应——


我希望每个操作都具有同步和异步函数,因为控制台和 GUI 应用程序都将使用该库,但我不想到处重复代码。

最好的答案是:不。

Stephen Toub 有两篇关于这个主题的优秀博客文章:

  • 我应该为同步方法公开异步包装器吗? http://blogs.msdn.com/b/pfxteam/archive/2012/03/24/10287244.aspx
  • 我应该为异步方法公开同步包装器吗? http://blogs.msdn.com/b/pfxteam/archive/2012/04/13/10293638.aspx

他建议将异步方法公开为异步,将同步方法公开为同步。如果您需要公开两者,则将公共功能封装在私有(同步)方法中,并复制异步/同步差异。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# 有异步函数调用同步函数或同步函数调用异步函数 的相关文章

随机推荐

  • 列出 MySQL JSON 字段的所有数组元素

    我有一个 JSON 字段来保存帖子的标签 id 1 content tags tag 1 tag 2 id 2 content tags tag 3 tag 2 id 3 content tags tag 1 tag 2 我只想列出所有标签
  • BouncyCastle 时间戳协议 |如何从 TimeStampToken 获取原始哈希值?

    我创建了一个时间戳请求从散列数据中提取数据并将其发送到 tsa TSA 回复了 已授予 响应 我已获得带有时间戳的字节数组 如何获取原始哈希数据 以便验证 TSA 发送的时间戳是否是我所要求的时间戳 提前致谢 Request TimeSta
  • 使用桌面浏览器的元视口标签设置视口

    我有一个客户提供的网站 宽度为 1440 像素 客户要求我使用以下命令将视口设置为 1440 像素 对于桌面浏览器 因此对于小于 1440 像素的屏幕不显示滚动条 它确实适用于移动设备 ipad 设备 我们可以使用它来设置视口 这也适用于桌
  • 如何在 Chrome 中调试 LESS?

    看起来 LESS 调试自一年前以来已经取得了相当大的进步 我想知道有多少人有使用 Chrome Canary 中的开发人员工具进行调试的经验 我试图确保当我调试文件时 元素的 CSS 显示为 LESS 文件 而不是 CSS 文件 当我需要知
  • Rails 在迁移之间共享代码(也称为关注点)

    我在相同的助手中有一些迁移 private def add earthdistance index table name options execute CREATE INDEX s earthdistance ix ON s USING
  • 使用 constexpr 编译时哈希

    我在一本用于在编译时创建 SDBM 哈希值的书中找到了这个示例 类 不幸的是它无法编译 无论是 c 11 还是 c 14 我正进入 状态error call to non constexpr function 我尝试了一下 但似乎无法完成这
  • JBoss EAR 部署顺序

    我有 5 个 EAR 需要部署 其中之一 local configuration ear 0 3 5 SNAPSHOT ear 是所有其他项的依赖项 并且它们在部署时需要它 即local configuration ear 0 3 5 SN
  • 使用 Angular 和 NodeMailer 发送电子邮件

    最近好吗 我正在尝试弄清楚如何使用 Angular 5 和 Node js 使用 nodemailer 发送电子邮件 我想要存档的是 当某些用户在页面中进行预约时 系统会获取提供的电子邮件 并在用户单击 安排我的 按钮时向用户发送一些信息
  • ColdFusion 条件记录计数

    好吧 SO 用户 这是一个看似不可能出错的条件语句 这很简单 但是 我不明白为什么它不能按预期方式工作
  • ASP NET Core MVC - 如何配置进程外会话状态?

    有没有办法使用 ASP NET Core MVC 配置进程外会话状态 使用 Windows 状态服务器或 SQL Server 重要的是会话数据由缓存支持 您需要将 IDistributedCache 实现添加到您的应用程序服务中 而不是内
  • Html2Pdf -Codeigniter -图像未加载

    我正在使用 HTML2PDF 库作为 codeigniter See https github com aiwmedia HTML2PDF CI https github com aiwmedia HTML2PDF CI我的问题是我无法使用
  • 使用 Unity 新输入系统的多个控制器

    我正在尝试将新的 Unity 输入系统与多个控制器一起使用 我尝试为每个角色创建输入操作 但这不起作用 所有角色同时移动 看起来角色并不关心控制器 而是关心输入 而不管控制器如何 也许我需要等待输入系统的最终版本 但是 我真的不想使用旧系统
  • 将微调器添加到 ActionBar(而不是导航

    我使用答案中的第二个选项向我的 ActionBar 添加了一个微调器here https stackoverflow com questions 8312344 how to add a dropdown item on the actio
  • Visual Studio - 如何使用相同的源创建两个项目

    我的解决方案由 2 个可执行项目和几个 dll 组成 Project1 是智能设备项目 Project2 是 Windows 窗体项目 这两个项目都使用相同的库 原因是我想在将库部署到设备上之前在 PC 上测试它 问题是 DLL 项目类型可
  • 延迟作业和 Mandrill:未初始化常量 Mandrill::API

    我有邮件服务 用户可以上传包含电子邮件和其他一些用户相关数据的 xls 文件来发送电子邮件活动 我遇到了一些超时问题 因为它需要几秒钟的时间来处理 因为我对每封要发送的电子邮件进行了一些验证和配置 例如 将记录保存到数据库 检查过去 30
  • 文件类型的可可图标?

    如果我有一个文件 我可以通过执行以下操作来获取图标 NSImage iconImage NSWorkspace sharedWorkspace iconForFile myFile png 但如果我只是想获取特定文件类型的图标 例如与 pn
  • 在 Apple 平台的 AArch64 汇编中,如何在一行中编写多个语句?

    我正在将一些 Arm64 汇编语言移植到 M1 其中一些是由 C 预处理生成的 其中单个 define宏生成多个以分号分隔的语句 不幸的是 在 M1 上 汇编器将分号视为注释字符 例如 define DEFUN NAME globl NAM
  • 可选框架不起作用(CoreAudioKit 不在模拟器上)

    为了让 MIDI 通过蓝牙工作 我需要使用CoreAudioKit框架 这工作完美 但我无法在模拟器上编译 使框架 可选 没有帮助 错误是ld framework not found CoreAudioKit 我认为它应该按照the doc
  • Azure-Container-Service 中的安装卷不适用于 traefik.toml 和 /var/run/docker.sock

    构建从 VSTS 到 Azure container service 的 CI CD 管道 我在安装 traefik toml 和 docker sock 文件时遇到了问题 部署使用 SSH 隧道创建文件夹 Deploy 并复制 docke
  • C# 有异步函数调用同步函数或同步函数调用异步函数

    我正在编写一个 C Net 4 5 库 用于执行常见的 sql 数据库操作 备份 恢复 执行脚本等 我希望每个操作都具有同步和异步函数 因为控制台和 GUI 应用程序都将使用该库 但我不想到处重复代码 所以在我看来 我有两个选择 编写在同步