c# - COM Interop 挂起会卡住整个 COM 系统。如何取消COM调用

标签 c# .net com interop

我正在使用通过 COM Interop 包装器公开的第三方 dll。然而,其中一个 COM 调用经常卡住(至少不会返回)。为了至少尝试使我的代码更加健壮,我异步包装了调用(_getDeviceInfoWaiterManualResetEvent)

var backgroundWorker = new BackgroundWorker();
      backgroundWorker.DoWork += 
        (sender, eventArgs) =>
          {
            var deviceInfo = _myCom.get_DeviceInfo(0);
            _serialNumber = deviceInfo.SerialNumber;
            _getDeviceInfoWaiter.Set();
          };
      backgroundWorker.RunWorkerAsync();
      var waitFifteenSecondsForGetInfo = new TimeSpan(0, 0, 0, 15);
      _getDeviceInfoWaiter.WaitOne(waitFifteenSecondsForGetInfo, true);
      if(String.IsNullOrEmpty(_serialNumber))
        throw new ArgumentNullException("Null or empty serial number. " +
            "This is most likely due to the get_DeviceInfo(0) COM call freezing.");

但是,对任何 COM 组件的下一次调用都会卡住代码。有什么我没有想到的,或者有什么方法可以防止我的主线程死亡?

更新

基本上,这是一个 COM 调用,每当新设备插入 PC 时就会调用,以便我们可以适本地记录信息。然而,正如我所说,如果这个组件正在等待,任何 COM 组件都会卡住(如果第三方锁定,则为我们自己的锁定的自定义 COM)

更新2

上面的代码确实有效,并且延迟了 UI 线程的挂起,直到下一次 COM 调用。尝试此解决方法的原因是 var deviceInfo = _myCom.get_DeviceInfo(0); 已锁定 UI 线程。但是,此信息并不重要,仅用于记录,因此此方法是为了允许“15 秒后放弃并继续”场景

这里的另一个解决方法是找到一种方法在 x 秒后取消 COM 调用?

最佳答案

更新 - OP 第二次更新后

如果您有一些有问题的组件,您始终可以通过使用以下方法使其使用更加健壮:

创建一个进程 (EXE),它包装该组件的使用并公开 API(例如通过任何 IPC 机制)。然后,您可以将该 EXE 作为一个单独的进程(从您的主 EXE 中)启动并使用它...如果您需要在一段时间后和/或满足某些条件时杀死该组件,您始终可以杀死该“包装 EXE”来自您的主 EXE...根据特定组件,在该“包装 EXE”中实现一些特殊的“清理代码”(可能在单独的线程中)甚至可能很有用,当您需要杀死该“包装 EXE”时执行该代码”。

由于您在 .NET 中实现此功能,您甚至可以将“包装器 EXE”作为主可执行文件中的“嵌入式资源”,甚至可以从 RAM 启动它,而无需将其写入文件系统...

关于c# - COM Interop 挂起会卡住整个 COM 系统。如何取消COM调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10321504/

相关文章:

c# - 调用非托管函数 char 返回 char *

c# - 我可以为我的所有 Web 应用程序共享一个类吗?

c# - 如何使用 "is"来测试类型是否支持 IComparable?

c# - 在 Entity Framework 中重复创建和删除数据库

delphi - 通过 IDispatch Invoke 实现识别 COM 事件的调用者

excel - 在 Excel COM 中为 Autohotkey 创建数据透视表和图表

.net - GAC – 程序集在 GAC 中,但 “Could not load file or assembly”

c# - 使用 Google SMTP 在 Azure Webjob 中发送电子邮件

c# - 如何在 WPF 中找到 UserControl 宽度?

c# - Microsoft ServiceBus 无序接收 BrokeredMessages