【问题标题】:C# app to C++ dll back to the C# app via callbacksC# 应用程序到 C++ dll 通过回调返回到 C# 应用程序
【发布时间】:2009-06-10 23:28:00
【问题描述】:

我正在编写一个调用 C++ dll 的 C# 应用程序。此 dll 是成像系统的设备驱动程序;获取图像时,可从库中逐行预览图像。 C++ dll 需要一个回调来填充预览,该回调主要由最终图像的大小、当前扫描的行和数据行本身组成。

问题是,从扫描停止和 C# 回调停止获取信息的时间开始存在相当严重的延迟。程序的流程是这样的:

  1. 在 C# 中为 C++ dll 分配回调
  2. 用户开始获取数据
  3. 设备启动
  4. dll 几秒后开始调用回调(正常)
  5. 设备完成成像
  6. dll 仍在为双倍图像形成时间调用回调。

同样的 dll 可以在 C++ 应用程序中正常工作;最后一步似乎没有延迟。但是,在 C# 中,如果我让回调立即返回,则延迟仍然存在;无论我在回调中做什么,它都在那里。

这种延迟是从非托管代码调用托管代码的固有限制,还是任何一方都可以做些什么来加快速度?我正在与 C++ 库编写者联系,因此可以从 C++ 端实现修复。

编辑:可以做一些简单的事情,比如命名管道吗?应用程序可以从自己的管道中读取吗?

【问题讨论】:

  • 所以听起来每个图像都会多次调用回调?多少?也许您可以通过让 C++ DLL 缓冲数据来将这些调用批处理到单个回调中?
  • 也许——如C++ dll声明缓冲区,将指针传递给C#应用程序,然后应用程序定期从缓冲区消费?

标签: c# c++ callback timing


【解决方案1】:

检查垃圾收集目标的本机回调的托管调试助手可能是罪魁祸首(它是否在调试器下处于调试模式?)

请参阅 Mike Stall 的 PSA: Pinvokes may be 100x slower under the debugger 博客文章。

【讨论】:

  • 我在发布配置中运行,该配置包含主应用程序和所有编译的库,关闭调试、关闭跟踪和优化。因此,根据每个解决方案的属性页面,不,我不在调试中。这也是vs2008,有关系吗?
  • 我也是通过双击可执行文件来运行的,而不是使用 vs2008 中有用的绿色箭头。
  • 如果您能够与 C++ 开发人员合作,请查看是否可以启用混合模式调试并跟踪问题。
【解决方案2】:

您是否正在跨互操作层进行任何时髦的数据编组?如果是这样,那么您可能会有很大的延迟,而它基本上是通过转换来编组您的所有图像数据。您可以轻松测试这一点,因为图像数据越大,所需时间越长

我想到的一些可能的替代方案是
1.使用内存映射文件,尽管您需要实现一个简单的信号量或信号系统来表示“我已经准备好数据”和“我已经使用了数据
2. 以混合模式编译 C++ dll(任何 C++ 代码都可以使用 /clr 标志编译成 .NET)然后使用 C#/CLI
3. 使用 Remoting 和 IPC 通道 - 可能有点矫枉过正,但值得一看

希望有帮助

【讨论】:

    【解决方案3】:

    事实证明,延迟是在 C++ 方面,一位发誓不是这样的开发人员。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-11
      • 2011-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多