1

コンポーネントをホストする .NET 4.0 Windows サービスがあります。私たちのプロジェクト リーダーは、特定のコンポーネントでメソッドを呼び出すと、パフォーマンスが低下すると言います。彼は、このパフォーマンスの低下を招くのは STA コンポーネントではないかと考えています。

この理論をテストするために、1 つのメソッドが整数を受け取り、整数の 2 倍を返す STA コンポーネントを作成するように依頼されました。このコンポーネントはサービスでホストされ、テストが実行されます。

このようなものは C# で作成できますか、それとも C++ で作成する必要がありますか?

可能であれば、いくつかのコードを含めていただけますか?

編集:(ハンの提案に基づくコード)

using System.Runtime.InteropServices;

namespace STADemo
{
    [ComVisible(true)]
    public class STAClass
    {
        public int Calculate(int value)
        {
            return 2*value;
        }
    }
}
4

2 に答える 2

3

これは、COM コクラスのプロパティです。[ComVisible] 属性を使用して作成できます。これを Regasm.exe に登録すると、ThreadingModel レジストリ キーが書き込まれます。どちらを「両方」に設定します。「アパートメント」に変更する必要があります。

これは非常に正気な方法ではありません。すでに知っていることを証明するだけです。あるスレッドから別のスレッドへの呼び出しのマーシャリングは、直接呼び出しよりもはるかに遅くなります。代わりにデバッガを使用してください。アンマネージ デバッグを有効にし、[デバッグ] + [ウィンドウ] + [スレッド] ウィンドウを監視します。コンストラクター呼び出しをステップ実行するときに別のポップアップが表示される場合は、COM コンポーネントに安全なホームを与えるために、COM がヘルパー スレッドを作成していることを示しています。おそらくサービスでは、自分で作成しない限り、デフォルトで STA スレッドがありません。Thread.SetApartmentState() 呼び出し。

于 2013-09-20T15:48:38.873 に答える
1

Windows サービスは MTA スレッド モデルを使用します。スローダウンの原因であると疑われる COM コンポーネントの正確なモデルを指定していません。'Apartment'それらがレジストリ エントリでまたは''(空白)としてマークされている場合ThreadingModel、すべての呼び出しが Windows サービスの現在のスレッドからコンポーネントをホストするために COM によって作成された専用スレッドにマーシャリングされるため、実際にパフォーマンスが低下する可能性があります。

本当にそれを証明する必要がある場合は、[ComRegisterFunction]. コンポーネントを としてマークするために使用する例を次に示します。ComRegisterFunctionApartment

この記事で説明されているように、クラス ファクトリ オブジェクトがスレッドを処理する方法には、シングル スレッド コンポーネントとアパートメント スレッド コンポーネントの間にまだ微妙な違いがあることに注意してください。シングル スレッド コンポーネントは非常にまれです。ほとんどの場合、コンポーネントはアパートメント スレッドですが、とにかくレジストリ キーを確認してください。

于 2013-09-20T23:35:39.073 に答える