From 3e76cbddf217e494410c176deee81be80f00c1e0 Mon Sep 17 00:00:00 2001 From: hrumhurum Date: Tue, 17 Aug 2021 19:57:41 +0300 Subject: [PATCH] Fixed memory leak in AppDomain.AssemblyResolve event subscription on subsequent script executions. --- src/Dotnet.Script.Core/ScriptRunner.cs | 44 +++++++++++++++----------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/src/Dotnet.Script.Core/ScriptRunner.cs b/src/Dotnet.Script.Core/ScriptRunner.cs index c9e23be7..38940695 100644 --- a/src/Dotnet.Script.Core/ScriptRunner.cs +++ b/src/Dotnet.Script.Core/ScriptRunner.cs @@ -34,30 +34,38 @@ public async Task Execute(string dllPath, IEnumerable var runtimeDepsMap = ScriptCompiler.CreateScriptDependenciesMap(runtimeDeps); var assembly = Assembly.LoadFrom(dllPath); // this needs to be called prior to 'AppDomain.CurrentDomain.AssemblyResolve' event handler added - AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => ResolveAssembly(args, runtimeDepsMap); + Assembly OnResolve(object sender, ResolveEventArgs args) => ResolveAssembly(args, runtimeDepsMap); - var type = assembly.GetType("Submission#0"); - var method = type.GetMethod("", BindingFlags.Static | BindingFlags.Public); - - var globals = new CommandLineScriptGlobals(ScriptConsole.Out, CSharpObjectFormatter.Instance); - foreach (var arg in commandLineArgs) - globals.Args.Add(arg); - - var submissionStates = new object[2]; - submissionStates[0] = globals; - - var resultTask = method.Invoke(null, new[] { submissionStates }) as Task; + AppDomain.CurrentDomain.AssemblyResolve += OnResolve; try { - _ = await resultTask; + var type = assembly.GetType("Submission#0"); + var method = type.GetMethod("", BindingFlags.Static | BindingFlags.Public); + + var globals = new CommandLineScriptGlobals(ScriptConsole.Out, CSharpObjectFormatter.Instance); + foreach (var arg in commandLineArgs) + globals.Args.Add(arg); + + var submissionStates = new object[2]; + submissionStates[0] = globals; + + var resultTask = method.Invoke(null, new[] { submissionStates }) as Task; + try + { + _ = await resultTask; + } + catch (System.Exception ex) + { + ScriptConsole.WriteError(ex.ToString()); + throw new ScriptRuntimeException("Script execution resulted in an exception.", ex); + } + + return await resultTask; } - catch (System.Exception ex) + finally { - ScriptConsole.WriteError(ex.ToString()); - throw new ScriptRuntimeException("Script execution resulted in an exception.", ex); + AppDomain.CurrentDomain.AssemblyResolve -= OnResolve; } - - return await resultTask; } public Task Execute(ScriptContext context)