看着博文之前,希望大家能看看 Allan. 的这篇文章。

http://www.cnblogs.com/zlgcool/archive/2008/10/12/1309616.html

之前逛园子时偶尔看到 Allan.这篇文章中提供了两种动态编译的方案,其中第一种方法由于卸载不太方便的确会导致内存方面的问题。而改良的第二种方法会将dll保存至bin目录,并通过加载这个dll,再调用dll中的方法,最后还有个删除dll的操作。这一系列操作势必会影响效率和浪费资源。我当时就想能否不简化这一系列的操作。所以才有了这篇博文,在这里首先感谢 Fish Li ,峰哥利用自己时间为园子里面的同志们解决问题,这种做法值得大家学习。

好了,开始说正文:

程序集的确是不能单独卸载,但程序域可以卸载,Allan. 的第二种方法可以借鉴修改。

先看看解决方案

关于在AppDomain中动态编译的解决方法

autoCompiled:提供对源代码动态编译的功能

AppDomainTest:调用程序

  Form1.cs:新建AppDomain、加载autoCompiled

  RemoteLoader.cs:提供远程访问调用

Winform中引用autoCompiled项目。

大致的思路就是将整个代码的编译过程(Compiled.cs类)全部拿到AppDomain中执行,RemoteLoader.cs提供远程访问。

winform代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Reflection;

namespace AppDomainTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            string strSourceCode = @"using System;
                                    namespace Test
                                    {
                                        public class HelloWorld
                                        {
                                            public string GetTime(string strName)
                                            {
                                                return  ""你好: "" + strName + "", 现在是北京时间: "" + System.DateTime.Now.ToString();
                                            }
                                        }
                                    }";

            object obj = CreateAppDomainExec(strSourceCode, "Test.HelloWorld", "GetTime");
            MessageBox.Show(obj.ToString());
        }

        /// <summary>
        /// 编译代码
        /// </summary>
        /// <param name="strSourceCode">源代码</param>
        /// <param name="typeName">typeName,需要根据这个创建编译后的实例 namespace+className</param>
        /// <param name="FunctionName">调用的方法名</param>
        /// <returns>返回值</returns>
        public object CreateAppDomainExec(string strSourceCode, string typeName, string FunctionName)
        {
            AppDomainSetup setup = new AppDomainSetup();
            setup.ApplicationName = "TestAppDomain";
            setup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;

            AppDomain appDomain = AppDomain.CreateDomain("CreateDomain", null, setup);
            RemoteLoader remoteLoader = (RemoteLoader)appDomain.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().GetName().FullName, typeof(RemoteLoader).FullName);//创建访问对象
            remoteLoader.LoadAssembly("autoCompiled");//加载编译代码的程序集

            object result = remoteLoader.CompiledExec(strSourceCode, typeName, FunctionName);//动态编译并执行

            //卸载程序集
            AppDomain.Unload(appDomain);
            appDomain = null;

            return result;
        }
    }
}
View Code

相关文章:

  • 2021-10-09
  • 2021-10-26
  • 2021-11-07
  • 2021-06-29
  • 2021-06-11
  • 2021-06-12
  • 2021-05-08
猜你喜欢
  • 2021-11-25
  • 2022-12-23
  • 2022-12-23
  • 2022-02-07
  • 2022-01-12
  • 2021-04-19
相关资源
相似解决方案