簡體   English   中英

在.NET中重新加載程序集而不創建新的AppDomain

[英]Reloading assemblies in .NET without creating a new AppDomain

我正在使用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編輯器不會消耗額外的內存。

所以,我想要完成的是外部裝配的“實時重裝”

.NET 4增加了對可以由GC卸載的可收集程序集的支持。

但是,這些受到嚴格限制:

  • 它們用於動態代碼生成,您不能只加載.dll文件
  • 他們無法定義COM互操作類型,P / Invoke方法,線程靜態字段,...

如果你有一個遵循這些限制的.dll,你可能能夠加載並重新發出IL代碼,使它看起來像是一個動態生成的.NET程序集。

除了動態方法和可收集的程序集之外,在不卸載整個AppDomain的情況下卸載代碼是不可能的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM