RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 876538
Accepted
Kir_Antipov
Kir_Antipov
Asked:2020-09-03 03:06:28 +0000 UTC2020-09-03 03:06:28 +0000 UTC 2020-09-03 03:06:28 +0000 UTC

在运行时编译和重新加载程序集

  • 772

同志们,我简单介绍一下情况:

我正在编写一个小型可扩展应用程序。为了让用户添加自己的功能,在程序的框架内,我创建了他们必须继承其类型的接口

同时,我还在应用程序内部进行了代码生成,以提供更大的便利。


假设我们有一个这样的界面:

namespace MyAppNamespace
{
    public interface INamed
    {
        string Name { get; }
    }
}

此外,在应用程序内部生成以下代码(并放入resultCode):

using MyAppNamespace;

public class Wrapper : INamed
{
    public string Name { get { return "Test"; } } 
}

我正在编译这个:

// Указываю, что на выходе мне не нужен исполняемый файл, а также что сборку нужно создать по указанному пути
CompilerParameters options = new CompilerParameters { GenerateExecutable = false, GenerateInMemory = false, OutputAssembly = $"{SavePath}.dll" };
options.ReferencedAssemblies.Add(new Uri(GetType().Assembly.CodeBase, UriKind.Absolute).LocalPath); // Добавляю ссылку на текущую сборку для наследования интерфейса
// Получаю результат компиляции
CompilerResults results = new Microsoft.CSharp.CSharpCodeProvider().CompileAssemblyFromSource(options, resultCode);
// Опустим проверки
// Загружаю сборку из массива байт (так как сам файл потом, возможно, может быть удален)
Assembly asm = Assembly.Load(File.ReadAllBytes(results.PathToAssembly));
// Создаю instance типа, который в сборке унаследован от нужного интерфейса
INamed named = (INamed)Activator.CreateInstance(asm.DefinedTypes.First(x => x.ImplementedInterfaces.Contains(typeof(INamed))).AsType());  
asm = null;
GC.Collect(); // Вычищаю сборку из памяти. По крайней мере, я хочу в это верить
return named;

之后,我可以安全地访问named.Name.
一段时间后,该对象被“丢弃”,直到用户明确表示他们想要使用它。在这种情况下,它需要从程序集中重新提取

但是有一个胖但是:如果我尝试以相同的方式加载程序集并再次从中获取类型,那么视觉上该过程将是成功的,但是当我尝试访问它时,named.Name会发生错误,即未找到定义它的程序集


我可以更正应用程序逻辑并一次性读取(也许它会更正确),但现在理解为什么会发生这种情况对我来说很重要:在第一次阅读时,一切都像发条一样工作,而在第二次阅读以相同的方式从同一个文件中,该过程是成功的,但是对象结果是“损坏”,因为当我尝试访问其属性时,我会收到一个错误,指出无法加载程序集

c#
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    MSDN.WhiteKnight
    2020-09-03T12:51:09Z2020-09-03T12:51:09Z

    我从内存中清除了程序集。至少这是我愿意相信的

    唉,这种信念是没有根据的。加载程序集的方式不仅不允许您在不卸载整个应用程序域的情况下从内存中卸载程序集,而且每次运行它时它还会再次从同一路径加载程序集(换句话说,这是一个当程序运行很长时间时内存不足的好方法)。

    创建Dictionary <string, Assembly>(其中字符串将是文件路径)并在其中缓存所有加载的程序集。如果您需要以某种方式考虑文件的内容,可以使用它来代替文件的路径 CRC/hash。或者将每个程序集加载到一个新的应用程序域中,然后可以将它们卸载(通常,这是创建带有扩展的应用程序时的常见做法)。

    • 2

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    是否可以在 C++ 中继承类 <---> 结构?

    • 2 个回答
  • Marko Smith

    这种神经网络架构适合文本分类吗?

    • 1 个回答
  • Marko Smith

    为什么分配的工作方式不同?

    • 3 个回答
  • Marko Smith

    控制台中的光标坐标

    • 1 个回答
  • Marko Smith

    如何在 C++ 中删除类的实例?

    • 4 个回答
  • Marko Smith

    点是否属于线段的问题

    • 2 个回答
  • Marko Smith

    json结构错误

    • 1 个回答
  • Marko Smith

    ServiceWorker 中的“获取”事件

    • 1 个回答
  • Marko Smith

    c ++控制台应用程序exe文件[重复]

    • 1 个回答
  • Marko Smith

    按多列从sql表中选择

    • 1 个回答
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Suvitruf - Andrei Apanasik 什么是空? 2020-08-21 01:48:09 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5