我正在使用通过COM Interop包装器公开的第三方dll。但是,其中一个COM调用通常会冻结(永远不会返回)。为了尽量至少使我的代码更健壮,我包的异步调用(_getDeviceInfoWaiter
是ManualResetEvent
)COM Interop hang冻结整个COM系统。如何取消COM调用
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组件第二天通话将冻结代码。有没有我没有想到的东西,或者有什么方法可以防止我的主线死亡?
UPDATE
基本上,这是一个COM调用每当一个新的设备插入到PC,使我们可以适当地将这些信息记录时调用。然而,正如我所说,任何 COM组件将如果这个人是等待(我们自己锁自定义COM如果第三方锁定)
更新2
上面的代码不工作冻结,并延迟UI线程的挂起,直到下一次COM调用。此尝试解决方法的原因是因为var deviceInfo = _myCom.get_DeviceInfo(0);
已经锁定了UI线程。然而,这个信息并不重要,仅用于日志记录,所以这种方法是为了允许“放弃并在15秒后继续”场景
这里的另一个解决方法是找到一种方法来取消COM x秒后通话?
我已更新我的问题以提供更多详细信息。让我知道,如果你仍然需要更多 – 2012-04-25 19:37:37
@JustinPihony我用一种方法更新了我的答案,这将有助于您的方案... – Yahia 2012-04-25 21:09:04
嗯,这听起来像这是最好的方式...不漂亮,但它应该工作。我非常感谢帮助 – 2012-04-25 21:20:13