2

C# から呼び出す ATL COM exe があります。参照を C# にインポートすると、すべてが正常に機能し、exe が生成され、関数を呼び出すことができます。ここで、これらの COM オブジェクトのいくつかをインスタンス化します。ときどき、そのうちの 1 つがハングします。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;
        }
    }
}

編集:これを「シングルユース」に設定できれば、すべてが思い通りに機能するようです。ただし、VS 2008 でこのオプションを設定する場所が見つかりません。

編集: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); 
    } 
   };
4

3 に答える 3

2

オブジェクトがハングするとどうなりますか? つまり、ハングしたことをどのように知ることができますか?

ハングした理由は多数ありますが、その 1 つは、システム内のどこかのスレッドが COM を初期化したが、Windows メッセージを送信していないことです。

COM サーバー exe のソース コードを管理していますか? これらの問題が存在しないインプロセスでロードできるように、DLL サーバーとしてははるかに単純な場合があります。

アップデート:

コメントの情報を考えると、COM exe-remoting を使用して 32/64 ビット サンキングの問題を解決しています。

COM exe サーバーでの私の経験は悲惨なものでした。COM DLL は実に単純なものですが、COM exe は非常に複雑で信頼性の低いものです。一部のインタラクティブな GUI シナリオでは、問題なく動作します。

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

これの利点は、64.exe が突然停止した場合、32.exe がソケットの読み取りでエラーを取得し、停止することを認識していることです。

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

于 2009-03-24T19:00:55.600 に答える
0

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

于 2009-03-26T21:46:01.693 に答える