簡體   English   中英

C#卸載臨時Appdomain時,主Appdomain使用臨時中的MethodInfo

[英]C# Unload temp Appdomain while main Appdomain uses MethodInfo from temp

我想制作一個可重載的匯編函數來編寫腳本。(這樣我可以更快地調試腳本)

dll生成也可以加載。 主要問題是,我正在主AppDomain中使用臨時AppDomain的功能。 該dll似乎也鏈接到我的主AppDomain,因為在程序運行時無法刪除它。 如果我從主AppDomain“上下文”中刪除所有MethodInfo引用,則刪除它沒有問題。

在這里,您可以看到程序的工作方式:

  • 從外部進程生成DLL
  • 通過(temp AppDomain).DoCallBack(...)加載DLL
  • 獲取Type&MethodInfo並調用它。
  • AppDomain.Unload(臨時AppDomain)

因此,如果我跳過第3步,則刪除dll沒有問題。 但是我無法檢查Function的返回是否真的顯示了更新后的值(我在腳本內進行了編輯)。

我已經在這里發布了每個步驟的源代碼:1。

//This actually isn`t as important for you    
Process assemblyGeneration = new Process();
    assemblyGeneration.StartInfo.FileName = AppDomain.CurrentDomain.BaseDirectory + @"lib\AssemblyCompiler.exe";
    assemblyGeneration.StartInfo.Arguments = "\"" + AppDomain.CurrentDomain.BaseDirectory + "script.dll\" \"" + source + "\" \"System.dll\"";
    assemblyGeneration.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
    assemblyGeneration.StartInfo.UseShellExecute = true;
    assemblyGeneration.Start();
    assemblyGeneration.WaitForExit();
    assemblyGeneration.Dispose();

2。

        _appDomain.DoCallBack(() =>
        {
            byte[] fileContent = File.ReadAllBytes(AppDomain.CurrentDomain.BaseDirectory + "script.dll");
            AppDomain.CurrentDomain.Load(fileContent);
        });

3。

MethodInfo info = _compiledScript.GetTypeFrom("LSCT.ScriptClass").GetMethod("DefineX");

        var func = (Func<double>) Delegate.CreateDelegate(typeof(Func<double>), info);
        double x = func();
        Console.WriteLine("Output was : " + x);

4。

AppDomain.Unload(_appDomain);

那么有沒有辦法解決這個問題,我無法重新加載DLL?

我想我已經解決了問題。 也許現在有性能問題,但是我還沒有檢查過。

無論如何,我創建了一個繼承MarshalByRefObject的新類,並使其從臨時AppDomain加載。

這是新類的代碼:

public class ProcessRunner : MarshalByRefObject
{
    public void Run()
    {
        Type typ = null;
        foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
        {
            Type t = asm.GetType("LSCT.ScriptClass");
            if (t != null)
            {
                typ = t;
                break;
            }
        }
        MethodInfo info = typ.GetMethod("DefineX");

        var func = (Func<double>)Delegate.CreateDelegate(typeof(Func<double>), info);
        double x = func();
        Console.WriteLine("Output was : " + x);
    }
}

以下是如何從臨時AppDomain調用它:

        ProcessRunner pr = (ProcessRunner)_appDomain.CreateInstanceFromAndUnwrap(Assembly.GetExecutingAssembly().Location, "Animation_Engine.UserInterface.Code.ProcessRunner");
        pr.Run();

注意:一旦從主AppDomain(例如,通過參數)傳遞任何引用到執行類,該dll將鏈接到主AppDomain,並且直到主AppDomain結束后才能卸載。

暫無
暫無

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

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