Reputation: 45
I have an asp core api. A route can execute several c# scripts from database to get some calcul results on the same context/globals.
So I have this code:
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;
}
This code leads me to memory leaks and the user cannot repeat these requests.
From my previous searches, I got some informations as my formulaContext class as to located in another project. So I put it in a model project outside my API project. But I still have this issue.
I tried several way to execute my script (with CSharpScript.Create or CSharpScript.EvaluateAsync for example) but the memory is still not released.
I also heard about AppDomain class to execute my script in sandbox and release memory after using but AppDomain is not used anymore in ASP.NET Core.
Thank you for help ;)
Upvotes: 1
Views: 2583
Reputation: 756
Why are you guys tripping out so much. Unloading of Assemblies/Types is NOT supported in DotNet Core and is not going to be until 3.0.
I am working on a CMS/VFS for DotNet Core and this is the single biggest obstacle at the moment.
Upvotes: 0
Reputation: 45
Ok I found a fix :
finally
{
GC.Collect();
}
The memory fall from more than 1 GB to 250 MG. I know, once an type or assembly is loaded, it can't be unloaded anymore but the formulas are very small so I suppose my memory was full because of the CSharpScript's compilation process.
I'm waiting now for the ability to unload assemblies to definitevely clean that. Apparently, it is planned : https://github.com/dotnet/coreclr/issues/552
Thank Tseng for your help.
Upvotes: 1