C#卸载临时Appdomain,而主Appdomain使用来自temp

时间:2016-03-12 19:06:15

标签: c# assembly dll appdomain

我想为脚本编写一个可重新加载的汇编函数。(所以我可以更快地调试脚本)

dll生成也可以加载。主要问题是,我在我的主AppDomain中使用了临时AppDomain的功能。 dll似乎也链接到我的主AppDomain,因为我无法在程序运行时删除它。 如果我从我的主AppDomain" context"中删除所有MethodInfo引用。那我删除它没有问题。

在这里您可以看到该程序的工作原理:

  • 从外部进程生成DLL
  • 通过(temp AppDomain).DoCallBack(...)
  • 加载DLL
  • 获取类型& MethodInfo并调用它。
  • AppDomain.Unload(temp AppDomain)

因此,如果我跳过第3步,我没有问题删除dll。但是我无法检查函数的返回是否真的显示更新的值(我在脚本中编辑)。

我已在此处发布了每个步骤的源代码: 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?

1 个答案:

答案 0 :(得分:0)

我想我已经解决了这个问题。也许现在有性能问题,但我还没有检查过。

无论如何,我创建了一个新类,它继承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结束之前无法卸载。