2

私は Com サーバーを作成しており、COM クライアントが予期せず閉じられたときの状況を検出するコードを書きました。この場合、COM サーバー コード内で COM サーバーを閉じる必要があります。

これどうやってするの?

UPD: COM サーバーがハングしたり、より正確には COM クライアントから COM サーバーにアタッチできない状況がありますが、COM サーバーを含むアプリケーションは生きているので、COM サーバーはすべての古い COM クライアントが切断されたことを検出できると思います/新しいクライアントが接続されていないため、クローズ/クラッシュし、アプリケーションが再起動します。

別のスレッドでCOMクライアントに次のコードを記述しました

while(not we are closing)
{
   unknown->QueryInterface(IComServer, &server);

   if (server)
     return;
}

そのため、COM クライアントは、サーバーが実際に動作する準備が整うまで待つことができます

UPD2: テスト済み: 12 分後に COM サーバーが閉じられました

4

3 に答える 3

5

COM は定期的にクライアントに ping を実行して、クライアントがまだ生きているかどうかを確認し、停止したクライアントからインターフェイスをダウンさせます。したがって、サーバーは最終的に見つけます。

于 2012-05-22T01:51:35.640 に答える
3

これは、2 つまたはプロセスが互いに相互運用している場合に常に存在する脆弱性です。そのうちの 1 つが終了し、もう 1 つのプロセスが実行を続けますが、終了したプロセスから別の要求が再び送信されることはないことに気付きません。アウトプロセス COM サーバーの場合、オブジェクトを破棄するために IUnknown::Release() を呼び出す人はいません。それ以外の場合、COM にはその問題に対する組み込みの修正プログラムがありません。インプロセス サーバーにはこの問題はありません。プロセスがクラッシュすると、サーバーも停止します。これも問題です。きれいなクリーンアップはありませんが、対処は簡単です。

サーバーをこれから回復させるには、自分で追加する必要があります。たとえば、サーバーがプロセス ハンドルを取得し、WaitForMultipleHandles() でクライアントがフォールオーバーしたことを検出できるように、クライアントにプロセス ID を渡させることができます。両方がマシン上にあると仮定すると、それは確かに COM の要件ではなく、サーバーが検出できるものでもありません。

于 2012-05-22T01:05:51.317 に答える
0

COM は、クライアントが終了した後しばらくしてアウトプロセス サーバーでサーバー側オブジェクトを解放しますが、そのオブジェクトで呼び出しが実行されていない場合に限ります。これが重要です。COM は進行中の呼び出しを停止できない可能性があります。したがって、解決策は、メソッドを短時間で実行し、数秒などの妥当な短い時間で終了することを保証することです。このようにして、クライアントが終了すると、新しい呼び出しがクライアントから到着せず、しばらくすると進行中の呼び出しが自然に終了し、タイムアウト後に COM がサーバー内のオブジェクトを解放し、サーバーが自然に停止する可能性があります。

于 2012-05-22T06:22:52.703 に答える