Re: Eval code and AppDomains
From: Scott Allen (scott_at_nospam.OdeToCode.com)
Date: Tue, 25 Jan 2005 20:11:19 -0800
Once an assembly is loaded it can't be removed, unfortunately the GC can't
The code runs inside the same process as you asp.net app so you won't see
a new process appear.
The only true way to get rid of the assembly and reclaim memory is to use
a new appdomain as you pointed out.
There is good article here: http://www.west-wind.com/presentations/dynamicCode/DynamicCode.htm
I'd also have some concern with performance if you need to scale this up
to a large number of users. Crossing app domains and generating these assemblies
can chew up CPU and memory if you need to do this 4 times per request.
-- Scott http://www.OdeToCode.com/blogs/scott/ > I have some complex logic which is fairly simply to build up into a > string. > I needed a way to Eval this string and return a Boolean result. > This code works fine to achieve that goal. > My question is what happens to the dynamically created assembly when > the > method is done running? Does GC take care of it? > Or is it stuck in RAM until the ASP.Net process is recycled? > This code executes pretty frequently (maybe 4 times per transaction) > and I > am concerned that I could be eating up RAM and not releasing it in my > ASP.Net application. > I would hate to have code like this bring down the web server just > because I > didn't clean it up correctly. > I took a quick look with Task Manager but when the code ran there was > no new process created. Is that because it is running inside the > ASP.Net process? > > I have seen a couple of posts that mention creating a separate > appdomain to > handle this type of issue. > Is there some complete sample code somewhere that shows how to do this > without accidentally re-loading the dynamic assembly into the ASP.Net > process? > Thanks in advance for any help. > > ====================================================================== > ====== > ==== > My web page calls the dynamic assembly code like this: where sbCode is > the > complex Boolean logic in String format. > Dim objEval As New EvalProvider > Dim objResult As Object = objEval.Eval(sbCode.ToString) > ====================================================================== > ====== > ==== > Dynamic Assembly code: > ====================================================================== > ====== > ==== > Imports Microsoft.VisualBasic > Imports System > Imports System.Text > Imports System.CodeDom.Compiler > Imports System.Reflection > Imports System.IO > Namespace myNamespace > > ''' <summary> > ''' Think about this: Your application does a lot of business logic, > some > of which requires complicated logical strings of code > ''' that may change over time to meet certain business conditions or > metadata. Wouldn't it be great if you could pull the most > ''' current string of code to be run out of your database based on > certain > stored procedure input parameters, and be sure it's run > ''' and you get back the desired result? In fact, the returned > string of > code may even be dynamically created based on some of the > ''' input parameters from the sproc itself. > ''' </summary> > ''' > ''' <remarks> > ''' http://www.eggheadcafe.com/articles/20030908.asp > ''' </remarks> > Public Class EvalProvider > > Public Function Eval(ByVal vbCode As String) As Object > Dim c As VBCodeProvider = New VBCodeProvider > Dim icc As ICodeCompiler = c.CreateCompiler() > Dim cp As CompilerParameters = New CompilerParameters > 'Note: this list much match the list of Imports in the sb.Append > below!! > cp.ReferencedAssemblies.Add("system.dll") > cp.ReferencedAssemblies.Add("system.data.dll") > cp.ReferencedAssemblies.Add("system.xml.dll") > cp.CompilerOptions = "/t:library" > cp.GenerateInMemory = True > Dim sb As StringBuilder = New StringBuilder("") > sb.Append("Imports System" & vbCrLf) > sb.Append("Imports System.Data" & vbCrLf) > sb.Append("Imports System.Xml" & vbCrLf) > sb.Append("Namespace myNamespace " & vbCrLf) > sb.Append("Class myDynamicLib " & vbCrLf) > sb.Append("public function EvalCode() as Object " & vbCrLf) > sb.Append(vbCode & vbCrLf) > sb.Append("End Function " & vbCrLf) > sb.Append("End Class " & vbCrLf) > sb.Append("End Namespace" & vbCrLf) > 'to debug your eval string uncomment this line > 'Debug.WriteLine(sb.ToString()) > Dim cr As CompilerResults = icc.CompileAssemblyFromSource(cp, > sb.ToString()) > Dim a As System.Reflection.Assembly = cr.CompiledAssembly > Dim o As Object > Dim mi As MethodInfo > o = a.CreateInstance("myNamespace.myDynamicLib ") > Dim t As Type = o.GetType() > mi = t.GetMethod("EvalCode") > Dim s As Object > s = mi.Invoke(o, Nothing) > Return s > End Function > > End Class > > End Namespace > ====================================================================== > ====== ==== >