COM Interop ラッパーを介して公開されているサード パーティの dll を使用しています。ただし、COM 呼び出しの 1 つがフリーズすることがよくあります (少なくとも返されることはありません)。少なくともコードをもう少し堅牢にするために、呼び出しを非同期にラップしました ( _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 コンポーネントを次に呼び出すと、コードがフリーズします。私が考えていないことはありますか、それともメインスレッドが死なないようにする方法はありますか?
アップデート
基本的に、これは新しいデバイスが PC に接続されるたびに呼び出される COM 呼び出しであり、情報を適切にログに記録できます。ただし、私が言ったように、これが待機している場合、任意のCOM コンポーネントがフリーズします (サードパーティがロックした場合、独自のロックのカスタム COM)。
更新 2
上記のコードは機能し、次の COM 呼び出しまで UI スレッドのハングを遅らせます。この回避策を試みた理由var deviceInfo = _myCom.get_DeviceInfo(0);
は、UI スレッドが既にロックされていたためです。ただし、この情報は重要ではなく、ログ記録にのみ使用されるため、このアプローチは「あきらめて 15 秒後に先に進む」シナリオを可能にすることです。
ここでの別の回避策は、x 秒後に COM 呼び出しをキャンセルする方法を見つけることですか?