2009-03-24 11 views
2

私はC#から呼び出しているATL COM EXEを持っています。私はC#への参照をインポートし、すべて正常に動作し、exeが生成され、私はそれの関数を呼び出すことができます。今、これらのCOMオブジェクトのいくつかをインスタンス化します。時にはそれらの1つがハングアップします。 COMオブジェクトを解放すると、まだ実行中のため、何も実行されません。私はそのプロセスを殺すことはできません。なぜなら、ちょうどうまく動作している他のすべてのオブジェクトを失うからです。だから、C#でCOMオブジェクトを管理する

  1. 本当に1つだけを殺す方法はありますか?
  2. リクエストされた各COMオブジェクトに対して1つのexeを起動する方法はありますか?
  3. クライアントが予期せず終了した場合、COM EXEは決してクリーンアップされません。これを修正する方法はありますか?

理想的には、オブジェクトインスタンスごとに1つのCOM EXEを起動し、Process.Kill()を実行することができます。これらのオプションのいずれかはオプションですか?私がオブジェクトを作成するために使用するクラスは以下の通りです。この場合、RandomID()(人工的に)は返すのに非常に時間がかかります。また、別の言語でこれを行う方法がある場合は、私もそれを試してみてください。ありがとう。

public class MyComObject:IDisposable 
{ 
    private bool disposed = false; 
    MyMath test; 

    public MyComObject() 
    { 
     test = new MyMath(); 
    } 

    public double GetRandomID() 
    { 
     if (test != null) 
      return test.RandomID(); 
     else 
      return -1; 
    } 

    public void Dispose() 
    { 
     Dispose(true); 

     GC.SuppressFinalize(this); 
    } 

    private void Dispose(bool disposing) 
    { 
     if (!this.disposed) 
     { 
      if (test != null) 
       Marshal.ReleaseComObject(test); 

      disposing = true; 
     } 
    } 
} 

EDIT:これを「シングルユース」に設定できるかどうかは、私が望むようにすべて動作します。しかし、私はどここのオプションは、VS 2008

EDITに設定する見つけることができません:オブジェクトがハングアップしたときに何が起こるGoogleグループ

class CMathServerModule : public CAtlExeModuleT<CMathServerModule> 
    { 

    public : 
    DECLARE_LIBID(LIBID_MathServerLib) 
    DECLARE_REGISTRY_APPID_RESOURCEID(IDR_MATHSERVER, "{2FA977F0-050C-4010-A09F-4FE6D75F3024}") 
    HRESULT RegisterClassObjects(DWORD dwClsContext, DWORD dwFlags) 
    throw() 
    { 
     dwFlags = ((dwFlags & ~(REGCLS_MULTIPLEUSE | REGCLS_MULTI_SEPARATE)) | 
       REGCLS_SINGLEUSE); 
     return CAtlExeModuleT<CMathServerModule>::RegisterClassObjects(dwClsContext, dwFlags); 
    } 
    }; 

答えて

2

に答えを発見されましたか?すなわち、それが掛かっていることをどのように知っていますか?

ハングアップしている理由はたくさんありますが、システムのどこかのスレッドがCOMを初期化しましたが、Windowsメッセージをポンピングしていないという理由があります。

COMサーバーexeのソースコードを制御しますか?これらの問題のどれも存在しない、インプロセスでロードできるように、DLLサーバーとしてはるかに簡単かもしれません。

更新:

コメントで情報を考えると、あなたには、32ビット/ 64ビットのサンクの問題を解決するためのCOMのexeファイル - リモートを使用しています。

COM EXEサーバーでの私の経験は悲惨です。 COM DLLは本当に簡単なことですが、COMのexeは深く複雑で信頼性の低いものです。いくつかのインタラクティブなGUIシナリオでうまく動作します。

しかし、あなた自身のIPCメカニズムを動かすほうが、奇妙に聞こえるかもしれません。実際にそれほど難しいことではありません。 64.exeがリスニングソケットを作成し、それがオンデマンドで作成する32.exeプロセスへのハンドルも保持していると仮定します。それは、好きなだけ多くの、または少ないものを作り、気まぐれにそれらを殺すことができます。 32.exeが起動すると、それはソケットに接続して読み込みます。これが動作する方法です。 64.exeは、受け入れられたソケット接続を介して命令を送信し、対応するプロセスハンドルと共に格納します。

これは、64.exeが突然死んだ場合、32.exeはソケットの読み込みにエラーを起こし、死に至ることも知っています。

ソケットを送信する形式は非常に簡単です。カウントされたバッファは理想的です(長さに続いて、その多くのバイトのデータを送信します)。

+0

私はソースを制御しますが、COMオブジェクトが32ビットで、C#ホストが64ビットであるため、out-of-procを作成する必要があります。 – Steve

+0

私は人工的にここでぶら下がりの動作を作成していますが、実際のコードもハングアップすることがあり、大きなプロジェクトなので、他の人にはそれを正しく(悲しいことに) – Steve

1

これが答えかどうかわかりませんが、Disposeメソッドのコードでは、処分をtrueに設定し、処分しません。 ReleaseComObjectへの複数の呼び出しを許可しています。

私は本当に廃棄を設定し、同じ問題があるかどうかを確認します。

0

COMインターフェイスをエクスポートするサービスを開発しましたが問題はありません。これはサーバープールで実行されています。
私の提案は、WinDbgでアプリケーションを監視し、デバッグ情報を含むコードをコンパイルし、pdbファイルを一緒にインストールすることです。

関連する問題