2

Microsoft のオールインワン コード サンプル: CSExeCOMServerに記載されているように、C# でプロセス外 COM サーバーを作成する場合、サーバーで (クライアントによって) 作成されるオブジェクトのスレッド モデルを制御するのは難しいようです。

作成されるオブジェクトは、WPF オブジェクトを使用するという事実のために STA に存在する必要があり、そのファクトリは、ExeCOMServer.csの 95 行目で示されているように登録されており、以下に貼り付けられています...

private void PreMessageLoop()
{
    //
    // Register the COM class factories.
    // 

    Guid clsidSimpleObj = new Guid(SimpleObject.ClassId);

    // Register the SimpleObject class object
    int hResult = COMNative.CoRegisterClassObject(
        ref clsidSimpleObj,                 // CLSID to be registered
        new SimpleObjectClassFactory(),     // Class factory
        CLSCTX.LOCAL_SERVER,                // Context to run
        REGCLS.MULTIPLEUSE | REGCLS.SUSPENDED,
        out _cookieSimpleObj);
    if (hResult != 0)
    {
        throw new ApplicationException(
        "CoRegisterClassObject failed w/err 0x" + hResult.ToString("X"));
    }

ただし、CreateInstance 関数は常に MTA 内の新しいスレッドで呼び出されます。ローカル サーバーのメイン スレッドが STA スレッドとしてマークされている (および検証されている) ことは問題ではないようです。

この問題に関するすべての資料は、作成されたオブジェクトのアパートメントが、ファクトリが登録されたスレッドのアパートメントと一致する必要があることを示唆しています。実際、これは ATL COM サーバー (Managed C++ と混合してオブジェクトを作成する) を使用する場合に当てはまるようですが、このメソッドは、初期化パラメーター、特に COM スレッド モデルであるワークフローに新しいスレッドを挿入しているように見えます。 、変更可能ではないようです。

大部分がアンマネージ コードで記述された COM サーバーに頼らずに、この問題を解決した人はいますか。

4

1 に答える 1

2

最近、64ビット相互運用機能用にいくつかのオブジェクトをホストするようにWinFormアプリケーションをセットアップするときに、非常によく似た状況が発生します。UIスレッドは、起動時に(STAThread属性を使用して)STAに入ります。すべてのコンストラクターがUIスレッド(STA)で実行されていることを発見するのにそれほど時間はかかりませんでしたが、他のすべてのメソッドは.Netが作成するワーカースレッド(MTA)で実行されます。

問題となっているのは実際にはMTAではありませんでしたが、UIにアクセスするメソッドがあり、それらは常にワーカースレッドで実行されているために問題が発生しています。.NetにUIスレッド(STA)への呼び出しを強制的にマーシャリングする方法を理解することはできませんでしたが、ContextBoundObjectとメソッドインターセプトを含む非常に汚いトリックを思いつきました。詳細については説明しませんが、System.Runtime.Remoting.MessagingおよびSystem.Runtime.Remoting.Contexts名前空間を確認できます。アイデアは、CCWをだまして、透過プロキシを相互運用オブジェクトとして考えさせることです。プロキシへのすべての呼び出しをインターセプトし、メッセージをUIスレッドに渡してから、メッセージをメソッド呼び出しに逆変換します。汚れた?はい。パフォーマンス?ひどい。しかし、それは機能します。

メソッドインターセプトコードを確認したい場合は、私にメールを送ってください。

于 2011-01-18T13:54:03.947 に答える