目 錄
1. 引用程序集... 1
2. 內存增漲的情況... 2
3. 內存穩定的情況... 4
1. 引用程序集
Roslyn 是微軟公司開源的 .NET 編譯器。編譯器支持 C# 和 Visual Basic 代碼編譯,並提供豐富的代碼分析 API。使用非常方便,增加引用腳本編譯引擎程序集:Microsoft.CodeAnalysis.CSharp.Scripting.dll,如下圖:
但是在使用過程中會出現內存增漲的情況,如果要解決這個問題,需要對代碼進行結構化處理。下面演示內存增漲和穩定兩種情況。
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()); } } }
在調試代碼的過程,每次執行代碼會把代碼生成一個新的程序集模塊,並且在新的程序域中加載,沒有找到卸載程序域和模塊的方法。如下圖:
正式運行編譯好的程序集,內存明顯增漲的比較快。如下圖:
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()); } } }
只會編譯和加載一次相同代碼的程序集模塊,編譯調試過程如下圖:
正式運行編譯好的程序集,運行一段時間,內存穩定在80多MB。如下圖:
物聯網&大數據技術 QQ群:54256083
物聯網&大數據項目 QQ群:727664080
網站:http://www.ineuos.net
QQ:504547114
微信:wxzz0151
博客:https://www.cnblogs.com/lsjwq
微信公眾號:iNeuOS
