4

私は ioc に登録された任意のインターフェースの暫定メソッドを実行するコンポーネントに取り組んでおり、実行の瞬間はさまざまなトリガーに依存します。実行するアクションをデータベースに保存できる必要があるため、必要になるまでメソッド名、タイプ、パラメーターのリスト (BLOB にシリアル化) をデータベースに保存しています。

トリガーが発生したら、タイプのインスタンスでメソッドを実行する必要があります。依存性注入を使用しているため、インターフェイス名がデータベースに保存されています(形式"Namespace.IInterface, AssemblyName"

Resolve<IInterface>()ioc コンテナーでメソッドを実行するには、そのインスタンスが必要Typeです。

Assembly assembly = System.Reflection.Assembly.Load(assemblyName);
Type service = assembly.GetType(typeName);
object instance = IOCContainer.Resolve(service);

私の質問は次のとおりです。

  • 含まれているアセンブリが既にアプリ ドメインに読み込まれていることが確実な場合、その名前から Type のインスタンスを取得するより良い方法はありますか? (単純に試してみましType.Load(typeName)たが、nullになりました)
  • 問題のアセンブリが既に読み込まれている場合、CLR はそのプロセスを最適化しますか (既に読み込まれているものを使用します)、またはアセンブリのリストを手動でキャッシュして、同じアセンブリを何度も繰り返し読み込むことによるパフォーマンスへの影響を防ぐ必要がありますか?
4

4 に答える 4

5
  • typeName使用するアセンブリ名(のようなものMyNamespace.MyType, MyAssembly version=1.0.0.0,publicKeyToken=12345etc)が含まれている場合Type.Load(typeName)、タイプは取得されますが、nullは取得されません。
  • CLRはアセンブリのロードを1回だけ処理します(コンテキストごとに1回、詳細はここにあります。この場合、コンテキストは同じままなので、リラックスしてキャッシュをCLRに任せる必要があります:))。
于 2012-09-04T10:31:40.193 に答える
3

含まれているアセンブリがすでにアプリドメインにロードされていると確信している場合、その名前からTypeのインスタンスを取得するためのより良い方法はありますか?(単にType.Load(typeName)で試しましたが、nullになりました)

いいえ。

問題のアセンブリがすでにロードされている場合、CLRはそのプロセスを最適化しますか(すでにロードされているものを使用)

はい。

各アセンブリは1回だけロードされます。

于 2012-09-04T10:32:15.580 に答える
2

問題のアセンブリが既に読み込まれている場合、CLR はそのプロセスを最適化します (既に読み込まれているものを使用)

この質問への回答は、MSDN の記事How the Runtime Locates Assemblies のステップ 2にあります。

要求されたアセンブリが以前の呼び出しでも要求されている場合、共通言語ランタイムは既に読み込まれているアセンブリを使用します。これは、アプリケーションを構成するアセンブリに名前を付けるときに影響を与える可能性があります。アセンブリの命名の詳細については、「アセンブリ名」を参照してください。


質問とは直接関係ありませんが、次のことにも役立ちます。

アセンブリに対する前の要求が失敗した場合、アセンブリに対する後続の要求は、アセンブリを読み込もうとせずにすぐに失敗します。.NET Framework バージョン 2.0 以降では、アセンブリ バインド エラーがキャッシュされ、キャッシュされた情報を使用して、アセンブリの読み込みを試行するかどうかが決定されます。

于 2012-09-04T13:34:39.750 に答える
1

パフォーマンスへの影響を確認するために、同じアセンブリを n 回読み込んでみました。また、割り当てられたメモリの合計が呼び出しごとに増加していることがわかりました。

試すには、次のようにします。

while (true)
{
    Assembly assembly = Assembly.LoadFrom("abc.dll");
    //monitor: AppDomain.CurrentDomain.MonitoringTotalAllocatedMemorySize
    //memory growing with each call
}

=============

次に、これを行って、アセンブリを一度だけロードしていることを確認しました。

var typeName = "Namespace.ClassName, Namespace";

while (true)
{
   var typeFound = Type.GetType(typeName);
   if (typeName == null)
   {
       Assembly assembly = Assembly.LoadFrom("abc.dll");
   }
   //monitor: AppDomain.CurrentDomain.MonitoringTotalAllocatedMemorySize
   //memory will not grow after first call
}
于 2017-01-10T06:40:52.580 に答える