关于C#中动态加载AppDomain的问题

 在操作系统中,利用进程可以对正在运行的应用程序进行隔离,每个应用程序被加载到单独的进程中,并为其分配虚拟内存,进程无法直接访问物理内存,只能通过操作系统将虚拟内存映射到物理内存中,并保证进程之间的物理内存不会重叠,但是进程最大的缺点就是效率问题,尤其是进程的切换开销很大,而进程间不能共享内存,所以不可能从一个进程通过传递指针给另一个进程。

  在.net中出现了一个新的概念:AppDomain——应用程序域,所有.NET应用程序都需要运行在托管环境中,操作系统能提供的只有进程,因此.NET程序需要通过AppDomain这个媒介来运行在进程中,同时使用该incheng提供的内存空间,只要是.NET的应用都会运行在某个AppDomain中。

  当我们运行一个.NET应用程序或者运行库宿主时,OS会首先建立一个进程,然后会在进程中加载CLR(这个加载一般是通过调用_CorExeMain或者_CorBindToRuntimeEx方法来实现),在加载CLR时会创建一个默认的AppDomain,它是CLR的运行单元,程序的Main方法就是在这里执行,这个默认的AppDomain是唯一且不能被卸载的,当该进程消灭时,默认AppDomain才会随之消失。

  一个进程中可以有多个AppDomain,且它们直接是相互隔离的,我们的Assembly是不能单独执行的,它必须被加载到某个AppDomain中,要想卸载一个Assembly就只能卸载其AppDomain。

  最近在我所参加的一个项目中要实现这样一个模块:定制一个作业管理器,它可以定时的以不同频率执行某些.Net应用程序或者存储过程,这里的频率可以是仅一次、每天、每周还是每月进行执行计划的实施,对于调用存储过程没什么好说的,但是调用.Net应用程序的时候就需要考虑如下问题:

  一旦Assembly被作业管理器的服务器调用,(比如某个执行计划正好要被执行了),在调用之前会将程序集加载到默认AppDomain,然后执行,这就有个问题,如果我需要做替换或者删除Assembly等这些操作的时候,由于Assembly已经被默认AppDomain加载,那么对它的更改肯定是不允许的,它会弹出这样的错误:

   除非你关掉作业管理服务器,然后再操作,显然这样做是很不合理的。

  并且默认AppDomain是不能被卸载的,那么我们该怎么办呢,我想到的方法是动态的加载Assembly,新建一个AppDomain,让Assembly加载到这个新AppDomain中然后执行,当执行完后卸载这个新的AppDomain即可

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C# ,使用 `dynamic` 关键字可以实现动态编程的功能。通过使用 `dynamic`,可以将变量的类型推迟到运行时进行确定,从而实现一些灵活的编程。 动态生成代码可以通过使用 `System.Reflection.Emit` 命名空间提供的类来实现。这些类允许你在运行时动态地创建和编译代码,并将其加载到当前应用程序域。 以下是一个使用 `dynamic` 和 `System.Reflection.Emit` 来动态生成一个简单的类的示例: ```csharp using System; using System.Reflection; using System.Reflection.Emit; class Program { static void Main(string[] args) { // 创建一个动态程序集和模块 AssemblyName assemblyName = new AssemblyName("DynamicAssembly"); AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly( assemblyName, AssemblyBuilderAccess.RunAndSave); ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("DynamicModule", "DynamicModule.dll"); // 定义一个名为 MyDynamicClass 的类 TypeBuilder typeBuilder = moduleBuilder.DefineType("MyDynamicClass", TypeAttributes.Public); // 添加一个名为 MyDynamicMethod 的方法 MethodBuilder methodBuilder = typeBuilder.DefineMethod( "MyDynamicMethod", MethodAttributes.Public | MethodAttributes.Static, typeof(void), new Type[] { typeof(string) }); // 向方法添加代码 ILGenerator il = methodBuilder.GetILGenerator(); il.Emit(OpCodes.Ldstr, "Hello, World!"); il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) })); il.Emit(OpCodes.Ret); // 完成类的定义 Type myDynamicClass = typeBuilder.CreateType(); // 创建一个实例并调用 MyDynamicMethod 方法 dynamic instance = Activator.CreateInstance(myDynamicClass); instance.MyDynamicMethod("test"); // 保存程序集 assemblyBuilder.Save("DynamicModule.dll"); } } ``` 以上代码会动态创建一个名为 `MyDynamicClass` 的类,并在其添加一个名为 `MyDynamicMethod` 的方法,在该方法输出 "Hello, World!"。最后,代码会将程序集保存到当前目录下的 `DynamicModule.dll` 文件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值