目       錄

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