Roslyn(CSharpScript).Net脚本编译引擎使用过程内存增涨与稳定的方式

  • A+
所属分类:.NET技术
摘要

目       录 1.      引用程序集… 1 2.      内存增涨的情况… 2

目       录

1.      引用程序集... 1

2.      内存增涨的情况... 2

3.      内存稳定的情况... 4

1.   引用程序集

     Roslyn 是微软公司开源的 .NET 编译器。编译器支持 C# 和 Visual Basic 代码编译,并提供丰富的代码分析 API。使用非常方便,增加引用脚本编译引擎程序集:Microsoft.CodeAnalysis.CSharp.Scripting.dll,如下图:

Roslyn(CSharpScript).Net脚本编译引擎使用过程内存增涨与稳定的方式

 

    但是在使用过程中会出现内存增涨的情况,如果要解决这个问题,需要对代码进行结构化处理。下面演示内存增涨和稳定两种情况。

2.   内存增涨的情况

  直接使用内部的API接口:CSharpScript.EvaluateAsync,完整代码如下:

using Microsoft.CodeAnalysis.CSharp.Scripting; using Microsoft.CodeAnalysis.Scripting;  namespace ConsoleApp1 {      public class Program     {         private static ScriptOptions scriptOptions=ScriptOptions.Default.WithEmitDebugInformation(false);         private static string script="int num=1+2;Write(num);return num;";         private static Custom custom = new Custom();         static void Main(string[] args)         {             while(true)             {                 MemoryRise();                  Thread.Sleep(10);             }         }          //内存内涨         public static void MemoryRise()         {             object result = CSharpScript.EvaluateAsync(script,scriptOptions,custom,typeof(Custom)).Result;              if(result!=null)             {                 Console.WriteLine(DateTime.Now.ToString ()+" Result:"+result.ToString ());              }         }     }      public class Custom     {         public void Write(int num)         {             Console.WriteLine("Custome.Write:"+num.ToString());         }     } }

   在调试代码的过程,每次执行代码会把代码生成一个新的程序集模块,并且在新的程序域中加载,没有找到卸载程序域和模块的方法。如下图:

Roslyn(CSharpScript).Net脚本编译引擎使用过程内存增涨与稳定的方式

   正式运行编译好的程序集,内存明显增涨的比较快。如下图:

Roslyn(CSharpScript).Net脚本编译引擎使用过程内存增涨与稳定的方式

3.   内存稳定的情况

  要避免对相同代码进行反复编译和加载模块,需要对代码进行特殊处理。代码如下:

using Microsoft.CodeAnalysis.CSharp.Scripting; using Microsoft.CodeAnalysis.Scripting;  namespace ConsoleApp1 {      public class Program     {         private static ScriptOptions scriptOptions=ScriptOptions.Default.WithEmitDebugInformation(false);         private static Script baseScript = CSharpScript.Create("", options: scriptOptions, globalsType: typeof(Custom));         private static Dictionary<string, Script<object>> loadScriptCache = new Dictionary<string, Script<object>> ();         private static string script="int num=1+2;Write(num);return num;";         private static Custom custom = new Custom();          static void Main(string[] args)         {             while(true)             {                 MemoryNormal();                  Thread.Sleep(10);             }         }          //内存稳定         public static void MemoryNormal()         {             if (!loadScriptCache.ContainsKey(script))                 loadScriptCache.Add(script, baseScript.ContinueWith<object>(script));              ScriptState<object> scriptState = loadScriptCache[script].RunAsync(custom).Result;                           if(scriptState.ReturnValue!=null)             {                 Console.WriteLine(DateTime.Now.ToString ()+" Result:"+scriptState.ReturnValue.ToString ());             }         }     }      public class Custom     {         public void Write(int num)         {             Console.WriteLine("Custome.Write:"+num.ToString());         }     } }

   只会编译和加载一次相同代码的程序集模块,编译调试过程如下图:

Roslyn(CSharpScript).Net脚本编译引擎使用过程内存增涨与稳定的方式

   正式运行编译好的程序集,运行一段时间,内存稳定在80多MB。如下图:

Roslyn(CSharpScript).Net脚本编译引擎使用过程内存增涨与稳定的方式


物联网&大数据技术 QQ群:54256083
物联网&大数据项目 QQ群:727664080
网站:http://www.ineuos.net
QQ:504547114
微信:wxzz0151
博客:https://www.cnblogs.com/lsjwq
微信公众号:iNeuOS
Roslyn(CSharpScript).Net脚本编译引擎使用过程内存增涨与稳定的方式