使第三方 I/O DLL 异步

Posted

技术标签:

【中文标题】使第三方 I/O DLL 异步【英文标题】:Making third party I/O DLL asynchronous 【发布时间】:2021-04-13 10:13:32 【问题描述】:

我需要使用第三方 DLL,它使用阻塞调用实现 TCP 套接字客户端(在 C++ 中)。所以基本上(伪代码);

void DoRequest()

  send(myblockingSocket,data); 
  recv(myblockingSocket,responsedata);

使用 async-await (不更改原始 DLL) 使这些调用在 .NET 中作为异步调用可访问的推荐方法是什么?

我阅读了:https://docs.microsoft.com/en-us/dotnet/standard/async-in-depth#deeper-dive-into-tasks-for-an-io-bound-operation 和 https://docs.microsoft.com/en-us/dotnet/csharp/async 以及其他几个页面,除了生成新任务之外没有找到其他解决方案,由于任务创建开销,不建议在 I/O 绑定操作上执行此操作。

【问题讨论】:

重写dll,或者从0写自己 生成线程或修改第三方库 您可以在要使用的 DLL 周围创建一个包装器,它将管理一个线程池,并且您可以将 DLL 调用委托给要异步执行的线程。 目的是什么?真正的异步调用在与操作系统交互时需要使用异步 IO,而这不可能更改 dll。您可以通过在单独的线程上运行调用来伪造它,但是您不会从异步 IO 中获得主要好处。然后你也可以将异步部分留给客户端在需要时使用。 这与“I/O 绑定操作”无关,问题是阻塞的不合作代码。使其异步的唯一方法是使用任务,无需担心开销。 【参考方案1】:

使用 async-await(不更改原始 DLL)使这些调用在 .NET 中作为异步调用可访问的推荐方法是什么?

没有推荐的解决方案,因为这是不可能的。要么必须更改/替换 DLL 本身以支持异步,要么异步调用将只是在后台线程上运行同步代码 - 我称之为“假异步”,因为它显示异步但无论如何,实际上正在占用一个线程。

...除了生成新任务之外没有找到其他解决方案,由于任务创建开销,不建议对 I/O 绑定操作执行此操作。

实际上是not recommended,原因有以下几点:

    它位于上游代码。如果不是,它会说“这个 API 是异步的”。这可能会导致消费者做出错误的决定,例如,在服务器场景中更喜欢异步 API。 它没有提供任何实际好处。使用Task.Run 实现方法会强制消费者使用额外的线程。如果您只是保持 API 同步,那么消费者可以根据需要选择是否使用Task.Run 调用它。

【讨论】:

谢谢!顺便说一句,链接中的文章不错。

以上是关于使第三方 I/O DLL 异步的主要内容,如果未能解决你的问题,请参考以下文章

vue路由自动加载、按组件异步载入vuex以及dll优化

java I/O—— 使用第三方jar包

FreeSWITCH第三方库(其他)的简单介绍

java I/O—— 不用maven导入第三方jar包

CAsyncSocket

初学python线程(转)