Re: Eval code and AppDomains

From: Scott Allen (scott_at_nospam.OdeToCode.com)
Date: 01/26/05


Date: Tue, 25 Jan 2005 20:11:19 -0800

Hi Joe:

Once an assembly is loaded it can't be removed, unfortunately the GC can't
help there.
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
> ======================================================================
> ====== ====
> 


Relevant Pages

  • Re: Eval code and AppDomains
    ... Do you know of any other way to Eval a String to get a Boolean result other ... >> Dim objEval As New EvalProvider ... >> Imports Microsoft.VisualBasic ...
    (microsoft.public.dotnet.framework.aspnet)
  • Code problem Help!
    ... Dim strCompname As String ... Dim strFirstname As String ... strFirstname & vbCrLf & _ ...
    (microsoft.public.access.formscoding)
  • Re: Macros coming from VS2003 not working right in VS2005 - Found it
    ... Dim vbcrlf As String = Microsoft.VisualBasic.Constants.vbCrLf ... Dim ts As TextSelection = DTE.ActiveDocument.Selection ... Exit Sub ...
    (microsoft.public.dotnet.general)
  • Re: Eval code and AppDomains
    ... Do you know of any other way to Eval a String to get a Boolean result ... Rick Strahl's article showed how to create a separate appdomain. ... > Based on how other assemblies work with an AppDomain that is correct. ... >> Dim objEval As New EvalProvider ...
    (microsoft.public.dotnet.languages.vb)
  • Re: Eval code and AppDomains
    ... Do you know of any other way to Eval a String to get a Boolean result ... Rick Strahl's article showed how to create a separate appdomain. ... > Based on how other assemblies work with an AppDomain that is correct. ... >> Dim objEval As New EvalProvider ...
    (microsoft.public.dotnet.framework.aspnet)