【发布时间】:2012-05-06 11:34:38
【问题描述】:
我正在使用通过 COM 互操作包装器公开的第三方 dll。但是,其中一个 COM 调用经常冻结(至少从不返回)。为了至少让我的代码更健壮一些,我异步包装了调用(_getDeviceInfoWaiter 是 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 组件都会冻结代码。有什么我没有想到的,或者有什么方法可以让我的主线程不死?
更新
基本上,这是一个 COM 调用,每当将新设备插入 PC 时都会调用它,以便我们可以适当地记录信息。但是,正如我所说,ANY COM 组件在此等待时将冻结(如果第三方锁定,我们自己的自定义 COM 将锁定)
更新 2
上面的代码确实有效,并将 UI 线程的挂起延迟到下一次 COM 调用。这种尝试解决方法的原因是var deviceInfo = _myCom.get_DeviceInfo(0); 已经锁定了 UI 线程。但是,此信息并不重要,仅用于日志记录,因此这种方法是允许“15 秒后放弃并继续前进”的场景
这里的另一种解决方法是找到一种方法在 x 秒后取消 COM 调用?
【问题讨论】: