我正在使用通過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