COM互操作挂起冻结整个COM系统。如何取消COM调用 [英] COM Interop hang freezes entire COM system. How to cancel COM call

查看:122
本文介绍了COM互操作挂起冻结整个COM系统。如何取消COM调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是通过COM互操作包装暴露第三方DLL。然而,在COM调用之一经常死机(从未至少返回)。要尽量至少让我的codeA一点更加坚固,我包的调用以异步方式( _getDeviceInfoWaiter 的ManualResetEvent

I am using a third party dll that is exposed via a COM Interop wrapper. However, one of the COM calls often freezes (never returns at least). To try to at least make my code a little more robust, I wrapped the call asynchronously (_getDeviceInfoWaiter is a ManualResetEvent)

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组件第二天通话将冻结code。有什么我没有想到的,或者是有一些方法来保持我的主线程不死吗?

However, the very next call to any COM component will freeze the code. Is there something I am not thinking of, or is there some way to keep my main thread from dying?

更新

基本上,这是被称为每当一个新设备插入电脑中,这样我们就可以适当地记录信息的COM调用。然而,正如我所说的,任何 COM组件会冻结,如果这个人是在等待(我们自己锁自定义COM如果第三方锁定)

Basically, this is a COM call that is called whenever a new device is plugged into the PC so that we can log the information appropriately. However, as I said, ANY COM component will freeze if this one is waiting (a custom COM of our own locks if the third party locked)

更新2

以上code不工作,并延迟挂在UI线程,直到下一个COM调用。这样做的原因试图解决方法是,因为 VAR deviceInfo = _myCom.get_DeviceInfo(0)已锁定该UI线程。然而,这种信息并不重要,仅用于日志记录,所以这种方法是允许的放弃和15秒后继续前进的场景

The above code DOES work, and delays the hanging of the UI thread until the next COM call. The reason for this attempted workaround was because var deviceInfo = _myCom.get_DeviceInfo(0); was already locking the UI thread. However, this info is not important and is only used for logging, so this approach is to allow for "give up and move on after 15 seconds" scenario

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

推荐答案

更新 - 从OP第二次更新后的

如果你有一些问题的组件,你可以随时让你对它的使用更强大的使用下面的方法:

IF you have some problematic component you can always make your usage of it more robust by using the following approach:

创建过程(EXE),其(经由任何IPC机制例如)封装该组件的使用和公开的API。然后,您可以启动EXE作为单独的进程(从主EXE),并用它...如果你需要经过一定的时间来杀死部件和/或在满足一定条件下可以随时杀死包装EXE从你的主EXE ......内包装EXE当你需要杀死它被执行依赖于特定组件上它甚至可能会执行一些特殊的清理code很有用(可能在一个单独的线程) 包装EXE。

Create a process (EXE) which wraps the usage of that component and exposes an API (for example via any IPC mechanism). You can then start that EXE as a separate process (from your main EXE) and use it... IF you need to kill that component after a certain time and/or when some condition is met you can always kill that "wrapper EXE" from your main EXE... depending on the specific component it might even be useful to implement some special "cleanup code" (possibly in a separate thread) within that "wrapper EXE" which gets executed when you need to kill that "wrapper EXE".

由于您使用.NET实施这一点,你甚至可以在你的主执行包装EXE为嵌入的资源,甚至从RAM启动它,而不将其写入到文件系统...

Since you are implementing this in .NET you can even have that "wrapper EXE" as "embedded resource" in your main executable and start it even from RAM without writing it to the filesystem...

这篇关于COM互操作挂起冻结整个COM系统。如何取消COM调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆