【发布时间】:2014-09-04 15:14:05
【问题描述】:
我正在使用 C# 开发游戏引擎 + 编辑器。这个想法是用户将他所有的游戏代码写在一个项目中,然后编辑器将加载它,因此它可以列出用户定义的类,并在场景编辑器中实例化它们。
搞乱(重新)加载 DLL 的概念,我可以加载 DLL,在外部程序集中定义的类上实例化和调用方法,重建外部程序集,然后在主机中再次加载它,而无需重新启动主人。这项工作(至少看起来像),但是它并没有从先前加载的程序集中释放内存。
加载器类:
public class Loader
{
// This DLL contains an implementation of ILoadable - ILoadable is declared in a shared project.
private const string AsmPath = @"D:\Dev\AsmLoading\AsmLoadingImpl\bin\Debug\AsmLoadingImpl.dll";
public ILoadable GetExternalLoadable()
{
var asmBytes = File.ReadAllBytes(AsmPath);
Assembly asm = Assembly.Load(asmBytes, null);
var loadableInterface = typeof(ILoadable);
var loadableImpl = asm.GetTypes().First(loadableInterface.IsAssignableFrom);
return (ILoadable)Activator.CreateInstance(loadableImpl);
}
}
运行GetExternalLoadable() 2 或 3 次,任务管理器显示我的主机程序中的 RAM 使用量增加了约 1mb,重复相同的操作将进一步增加它,而不会减少。
有没有办法解决这个问题?我知道 Unity 正在做类似的事情,除了它们实际上自己编译外部程序集,但是当我触发重新编译几次时,Unity 编辑器不会消耗额外的内存。
所以,我想要完成的是“实时重新加载”外部程序集。
【问题讨论】:
-
可能 unity 正在使用单独的应用程序域来运行这些程序集 :) 来自:msdn.microsoft.com/en-gb/library/ms173101.aspx 如果不卸载包含它的所有应用程序域,就无法卸载单个程序集。即使程序集超出范围,实际的程序集文件仍将保持加载,直到包含它的所有应用程序域都被卸载。
-
@OndrejSvejdar 是什么让你这么认为? :)
-
如果要卸载程序集,唯一的方法是使用新的 AppDomain 并卸载该 AppDomain。
-
@mikez 是的,我知道,只是想知道是否有其他方法。
-
@OndrejSvejdar 我只是查看了 Unity 对象树,但没有一个
[Serializable]或MarshalByRefObject:)
标签: c# .net .net-assembly