1

COM Interop ラッパーを介して公開されているサード パーティの dll を使用しています。ただし、COM 呼び出しの 1 つがフリーズすることがよくあります (少なくとも返されることはありません)。少なくともコードをもう少し堅牢にするために、呼び出しを非同期にラップしました ( _getDeviceInfoWaiteris 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 呼び出しをキャンセルする方法を見つけることですか?

4

2 に答える 2

3

UPDATE - OP からの 2 回目の更新後

問題のあるコンポーネントがある場合は、次のアプローチを使用して、いつでもその使用をより堅牢にすることができます。

そのコンポーネントの使用をラップし、API を公開するプロセス (EXE) を作成します (たとえば、任意の IPC メカニズムを介して)。次に、そのEXEを(メインのEXEから)別のプロセスとして開始して使用できます...特定の時間の後にそのコンポーネントを強制終了する必要がある場合、および/または何らかの条件が満たされた場合、いつでもその「ラッパーEXE」を強制終了できますメインEXEから...特定のコンポーネントによっては、その「ラッパーEXE」を強制終了する必要があるときに実行される「ラッパーEXE」内に特別な「クリーンアップコード」を(おそらく別のスレッドで)実装すると便利な場合もあります"。

これを .NET で実装しているので、その「ラッパー EXE」をメインの実行可能ファイルの「埋め込みリソース」として持つこともでき、ファイルシステムに書き込まずに RAM から起動することもできます...

于 2012-04-25T18:30:14.577 に答える
1

サード パーティの DLL には、何らかの種類の無期限の待機、ループ、またはデッドロックが内部にあります。このように回避しようとしてもうまくいきません。ハングしている呼び出しをワーカー スレッドに割り当てた可能性がありますが、そのスレッドは消えません。その呼び出しでハングし続けます。

COM コンポーネントへの次の呼び出しがフリーズする可能性が最も高いのは、前の呼び出しがフリーズしたためです。おそらく、ハングする前に前のロックが取得したロックを取得しようとしています。または、依存する理由ではなく、まったく同じ理由でハングしている可能性があります。

このサードパーティのものの開発者/ベンダーに連絡して、何らかの方法で悪用していないかどうか尋ねてください。欠落している前提条件はありますか。実行されなかったいくつかの初期化。必要な設定など

于 2012-04-25T18:30:31.300 に答える