Dllを読み込んだ後にGetTypes()を実行する時間を確認する必要があります。コードは次のとおりです。
Assembly assem = Assembly.LoadFrom(file);
sw = Stopwatch.StartNew();
var types1 = assem.GetTypes();
sw.Stop();
double time1 = sw.Elapsed.TotalMilliseconds;
Dllをアンロードおよびリロードして、GetTypes()の再実行に費やす時間を確認したいと思います。
assem = null
で十分ですか?残念ながら、一度ロードされたアセンブリをアンロードすることはできません。ただし、AppDomainをアンロードできます。できることは、新しいAppDomain(AppDomain.CreateDomain(...))を作成し、このappdomainにアセンブリをロードして作業し、必要に応じてAppDomainをアンロードすることです。 AppDomainをアンロードすると、ロードされたすべてのアセンブリがアンロードされます。 ( 参照 を参照)
ガベージコレクターを呼び出すには、次を使用できます。
GC.Collect(); // collects all unused memory
GC.WaitForPendingFinalizers(); // wait until GC has finished its work
GC.Collect();
GCはバックグラウンドスレッドでファイナライザを呼び出します。そのため、すべてを削除したことを確認するために、Collect()を再度呼び出して待機する必要があります。
別のAppDomainを使用できますか?
AppDomain dom = AppDomain.CreateDomain("some");
AssemblyName assemblyName = new AssemblyName();
assemblyName.CodeBase = pathToAssembly;
Assembly assembly = dom.Load(assemblyName);
Type [] types = Assembly.GetTypes();
AppDomain.Unload(dom);
LoadFrom()
またはLoadFile()
を使用する代わりに、File.ReadAllBytes()
でLoad
を使用できます。これにより、アセンブリファイルは使用されませんが、それを読み取り、読み取りデータが使用されます。
コードは次のようになります
Assembly assem = Assembly.Load(File.ReadAllBytes(filePath));
sw = Stopwatch.StartNew();
var types1 = assem.GetTypes();
sw.Stop();
double time1 = sw.Elapsed.TotalMilliseconds;
From here ファイルに含まれるすべてのドメインがアンロードされない限り、ファイルをアンロードできません。
お役に立てれば。:)
現在のAppDomainからアセンブリをアンロードすることはできません。ただし、新しいAppDomainを作成し、そこにアセンブリをロードし、新しいAppDomain内でコードを実行してからアンロードできます。次のリンクを確認してください: [〜#〜] msdn [〜#〜]
残念ながら、アセンブリをアンロードすることはできません。さらに、appdomainsを使用している場合は、メインアプリケーションのapi /アセンブリと通信できなくなります。
問題に関する最良の説明はここにあります:
スクリプトホスティングガイドライン http://www.csscript.net/help/Script_hosting_guideline_.html
メインアプリケーションと通信せずにC#コードを実行する場合-C#スクリプトAPIを統合するのが最善の方法です。
また、統合には次のパッケージが必要です。
C#スクリプト: http://www.csscript.net/CurrentRelease.html
Visual Studio拡張機能: https://marketplace.visualstudio.com/items?itemName=oleg-shilo.cs-script
ただし、C#スクリプトからアプリケーションに通信する場合-アセンブリ名を絶えず変更して同じappDomainを使用するのは現時点では唯一の方法ですが、残念ながらRAMとディスク領域を消費します。
コードサンプルの実行方法-ここから参照できます。
https://github.com/tapika/cppscriptcore CsScriptHotReload.sln
そして、ここにデモビデオがあります:
https://drive.google.com/open?id=1jOECJj0_UPNdllwF4GWb5OMybWPc0PUV
依存アセンブリなしで初期アセンブリのみをロードする場合は、AppDomainでAssembly.LoadFile
を使用し、完了時にAppDomainをアンロードできます。
アセンブリをロードして操作するローダークラスを作成します。
class Loader : MarshalByRefObject
{
public void Load(string file)
{
var Assembly = Assembly.LoadFile(file);
// Do stuff with the Assembly.
}
}
次のように、別のアプリドメインでローダーを実行します。
var domain = AppDomain.CreateDomain(nameof(Loader), AppDomain.CurrentDomain.Evidence, new AppDomainSetup { ApplicationBase = Path.GetDirectoryName(typeof(Loader).Assembly.Location) });
try {
var loader = (Loader)domain.CreateInstanceAndUnwrap(typeof(Loader).Assembly.FullName, typeof(Loader).FullName);
loader.Load(myFile);
} finally {
AppDomain.Unload(domain);
}