我有一个asp核心api。一条路由可以从数据库中执行多个c#脚本,从而在相同的上下文/全局变量上获得一些计算结果。
所以我有这样的代码:
public static async Task<FormulaEvalException> TryEvalAsync<T>(this T formulaContext) where T : FormulaContext
{
FormulaEvalException res = null;
ScriptState state = null;
var scriptOptions = ScriptOptions.Default.WithReferences("System", "System.Linq", "System.Globalization", "Microsoft.CSharp").WithImports(new[] { "System", "System.Linq", "System.Math", "System.Globalization", "System.Collections.Generic" });
foreach (var formulaList in formulaContext.AllFormulas.Values)
{
foreach (var formula in formulaList)
{
formulaContext.CurrentFormula = formula;
try
{
if (state == null)
{
state = await CSharpScript.RunAsync(formula.Script, scriptOptions, formulaContext);
}
else
{
state = await state.ContinueWithAsync(formula.Script);
}
var result = state.ReturnValue;
if (result == null)
{
if (res == null)
{
res = new FormulaEvalException(formula.Title + " : No result");
}
continue;
}
formula.Result = result;
}
catch (CompilationErrorException ex)
{
if (res == null)
{
res = new FormulaEvalException(formula.Title + ex.Message);
}
continue;
}
catch
{
continue;
}
}
}
return res;
}这段代码会导致内存泄漏,用户无法重复这些请求。
从我之前的搜索中,我得到了一些信息作为我的formulaContext类,它位于另一个项目中。所以我把它放在API项目之外的一个模型项目中。但是我仍然有这个问题。
我尝试了几种方法来执行我的脚本(例如,使用CSharpScript.Create或CSharpScript.EvaluateAsync ),但是内存仍然没有释放。
我也听说过AppDomain类在沙箱中执行我的脚本,并在使用后释放内存,但在ASP.NET核心中不再使用AppDomain。
感谢您的帮助;)
发布于 2018-11-19 19:30:15
好的,我找到了一个解决方法:
finally
{
GC.Collect();
}内存从1 GB以上下降到250 MG。我知道,一旦加载了类型或程序集,它就不能再卸载了,但是公式非常小,所以我想我的内存已经满了,因为CSharpScript的编译过程。
我现在正在等待卸载程序集的能力来彻底清理它。显然,这是有计划的:https://github.com/dotnet/coreclr/issues/552
感谢曾同学的帮助。
发布于 2018-11-28 22:34:28
你们为什么要这么频繁地外出。卸载程序集/类型在DotNet核心中不受支持,直到3.0才会支持。
我正在为DotNet核心的内容管理系统/虚拟文件系统工作,这是目前最大的单一障碍。
https://stackoverflow.com/questions/53360075
复制相似问题