C# 卸载使用Assembly.LoadFrom()加载的程序集
我需要检查加载dll后运行GetTypes()的时间量。 代码如下C# 卸载使用Assembly.LoadFrom()加载的程序集,c#,garbage-collection,load,gettype,C#,Garbage Collection,Load,Gettype,我需要检查加载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足够好
Assembly assem = Assembly.LoadFrom(file);
sw = Stopwatch.StartNew();
var types1 = assem.GetTypes();
sw.Stop();
double time1 = sw.Elapsed.TotalMilliseconds;
我想卸载并重新加载dll,以检查再次运行GetTypes()所花费的时间
- 我怎样才能卸下它
足够好吗李>assem=null
- 是否有明确的方法调用垃圾收集器来回收分配给assem的资源
- 不幸的是,一旦加载程序集,就无法卸载它。但您可以卸载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(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,将程序集加载到其中,在新AppDomain中执行一些代码,然后卸载它。检查以下链接:您无法从当前AppDomain卸载程序集。但您可以创建新的AppDomain,将程序集加载到其中,在新AppDomain中执行一些代码,然后卸载它。检查以下链接:是否可以使用其他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);
你能使用另一个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);
您可以将
Load
与File.ReadAllBytes()一起使用,而不是使用LoadFrom()
或LoadFile()
。这样,它不使用程序集文件,但将读取它并使用读取数据
然后,您的代码将如下所示
Assembly assem = Assembly.Load(File.ReadAllBytes(filePath));
sw = Stopwatch.StartNew();
var types1 = assem.GetTypes();
sw.Stop();
double time1 = sw.Elapsed.TotalMilliseconds;
从中,我们无法卸载该文件,除非卸载该文件包含的所有域
希望这有帮助。您可以使用Load
和File.ReadAllBytes()
来代替LoadFrom()或LoadFile()
。这样,它不使用程序集文件,但将读取它并使用读取数据
然后,您的代码将如下所示
Assembly assem = Assembly.Load(File.ReadAllBytes(filePath));
sw = Stopwatch.StartNew();
var types1 = assem.GetTypes();
sw.Stop();
double time1 = sw.Elapsed.TotalMilliseconds;
从中,我们无法卸载该文件,除非卸载该文件包含的所有域
希望这能有所帮助。:程序集很遗憾无法卸载,而且,如果您使用appdomains,那么它将阻止您与主应用程序的api/程序集通信
有关问题的最佳描述可在此处找到:
脚本托管指南
如果您想在不与主应用程序通信的情况下运行C#代码,那么最好的方法是集成C#脚本API:
对于集成,您需要以下软件包:
C#脚本:
Visual studio扩展:
然而,如果您希望从C#脚本到应用程序进行通信,那么使用相同的appDomain并不断更改程序集名称是目前唯一的方法,但不幸的是,这会占用ram和磁盘空间
代码示例如何执行此操作可以在此处找到:
CsScriptHotReload.sln
下面是演示视频:
程序集很遗憾无法卸载,而且,如果您使用appdomains,则会阻止您与主应用程序的api/程序集通信
有关问题的最佳描述可在此处找到:
脚本托管指南
如果您想在不与主应用程序通信的情况下运行C#代码,那么最好的方法是集成C#脚本API:
对于集成,您需要以下软件包:
C#脚本:
Visual studio扩展:
然而,如果您希望从C#脚本到应用程序进行通信,那么使用相同的appDomain并不断更改程序集名称是目前唯一的方法,但不幸的是,这会占用ram和磁盘空间
代码示例如何执行此操作可以在此处找到:
CsScriptHotReload.sln
下面是演示视频:
如果只希望加载初始程序集而不加载其任何从属程序集,则可以在AppDomain中使用assembly.LoadFile
,然后在完成后卸载AppDomain
创建加载程序类以加载和使用程序集:
类加载器:MarshallByRefObject
{
公共无效加载(字符串文件)
{
var assembly=assembly.LoadFile(文件);
//对组件进行处理。
}
}
在单独的应用程序域中运行加载程序,如下所示:
var domain=AppDomain.CreateDomain(nameof(Loader)、AppDomain.CurrentDomain.defence、new-AppDomainSetup{ApplicationBase=Path.GetDirectoryName(typeof(Loader.Assembly.Location)});
试一试{
var loader=(loader)domain.CreateInstanceAndUnwrap(typeof(loader).Assembly.FullName,typeof(loader).FullName);
loader.Load(myFile);
}最后{
卸载(域);
}
如果只希望加载初始程序集而不加载其任何从属程序集,则可以在AppDomain中使用assembly.LoadFile
,然后在完成后卸载AppDomain
创建加载程序类以加载和使用程序集:
类加载器:MarshallByRefObject
{
公共无效加载(字符串文件)
{
var assembly=assembly.LoadFile(文件);
//对组件进行处理。
}
}
在单独的应用程序域中运行加载程序,如下所示:
var