1

C# COM 可視クラスを登録 (RegAsm) した後CoCreateInstance(__uuidof(myclass))、最初だけ時間がかかり、同じクライアント プロセスでの後続の試行は即座に解決されます。なぜ時間がかかるのですか?NGen は私にとって選択肢ではありません。

私の COM サーバーは C# で、クライアントは MFC/ATL です

CComPtr<namespace::Imyclass> obj;
hrx = obj.CoCreateInstance(__uuidof(namespace::myclass));
4

3 に答える 3

1

への最初の呼び出しでCoCreateInstanceは、.NET ランタイムをプロセスにロードして初期化する必要があります。次に、DLL をロードして「検証」し、マシン コードにコンパイルする必要があります (ただし、ジャスト イン タイムは起動の高速化に大いに役立ちます)。.NET ランタイムは、アセンブリのメタデータを解析し、「COM 呼び出し可能ラッパー」( http://msdn.microsoft.com/en-us/library/f07c8z1c.aspx ) を動的に生成してコンパイルする必要もあります。アンマネージド COM ワールドとマネージド .NET ランタイムの間を橋渡しするプロキシ。コードが使用する可能性のある追加のライブラリも、ロードして検証し、場合によってはマシン コードにコンパイルする必要があります (NGEN 化されていない場合)。

これは本質的に高価なプロセスです。あなたが言及した遅延は前例のないものではありません。

物事をスピードアップするためにできることはあまりないと思います。起動後すぐにオブジェクトを作成することで、プログラムの有効期間の早い段階で打撃を受けることができるかどうかを検討することをお勧めします。速度は向上しませんが、ユーザー エクスペリエンスが劇的に向上する可能性があります。プログラムが遅延を許容できない場合は、.NET を使用して COM オブジェクトを記述しないでください (具体的には、プロセスで .NET を使用しないでください。これは、COM を使用することの問題ではありません。 .NET の読み込みに関する問題)

ちなみに、これが.NETでシェル拡張機能を書くことが...「非常に推奨されない」理由の1つです。.NET の起動パフォーマンスについても触れている、この件に関する最近の投稿を参照してください: http://blogs.msdn.com/b/oldnewthing/archive/2013/02/22/10396079.aspx

(そのため、実行しているクライアントの種類を先に尋ねました。既に .NET マネージ コードを実行しているクライアントは .NET ランタイムに依存しており、これらの遅延の影響を受けません)

于 2013-04-17T07:08:33.937 に答える
0

この遅延が最初の読み込み(コンピューターの起動後)のみの場合、これはすべてのライブラリの読み込みが原因です。開始後の最初の遅延(または .NET を長時間使用しない場合)は常に遅くなります。(ミセリの回答を参照)

読み込みのたびに遅延が発生することもあります。今日、インターネット接続も遅延の原因になる可能性があることがわかりました。

測定値:

  1. イーサネットなし、WiFi 接続遅延なし: 94 ミリ秒 (Win7) / 1.5 (WinXP)
  2. Windows XP: インターネット接続(プロキシと非標準ゲートウェイを使用。すべてのポートが許可されているわけではありません) : 4-5 秒 (WinXP)
  3. インターネットではなくイーサネットに接続: 10 秒 (Win7)
  4. イーサネットへの接続直後(Windows はインターネット接続をテストします。ネットワーク アイコンの青い円) : 30 秒 (Win7)
  5. インターネット接続(プロキシと非標準ゲートウェイを使用。少数のポートのみが許可されます) : 30 秒 (Win7)

*非標準ゲートウェイ: 許可される TCP ポートと接続は、コンピューターごとに異なります (WinXP と Win7 では異なります)。

Windows 7 (x64) および WinXP でテスト済み。顧客から苦情があり、 CoCreateInstanceの遅延を見つけたのでテストしました。ロードされたライブラリは c# であり、署名されています (snk で署名されたアセンブリと、実行可能ファイルに署名するための標準証明書を使用)

次も参照してください。 ?forum=sqlce

于 2013-11-25T14:21:08.227 に答える
0

への最初の呼び出しでCoCreateInstanceは、レジストリとファイル システムを調べて、適切なコードをロードし、初期化を許可し、最後にファクトリを呼び出して、要求したインスタンスを作成する必要があります (見つかった場合)。

2 番目の呼び出しは、これらの前の手順から大きな恩恵を受けます。最初の呼び出しが成功した場合、コードは既に読み込まれて初期化されており、ファクトリをもう一度呼び出すだけで済みます。

于 2013-04-17T06:28:31.737 に答える