Re: Eval code and AppDomains

From: Joe Fallon (jfallon1_at_nospamtwcny.rr.com)
Date: 01/26/05


Date: Wed, 26 Jan 2005 09:38:59 -0500

Scott,
That was 4 times per transaction which is a single page in a large site. It
is not every hit.

I think I have seen that article - I will read it closely. I use Rick's
stuff in other areas.

Do you know of any other way to Eval a String to get a Boolean result other
than dynamically generating the assembly as shown below?

Do you know if Eval will be a built-in function in ver 2.0 of the .Net
framework?

Thanks.

-- 
Joe Fallon
"Scott Allen" <scott@nospam.OdeToCode.com> wrote in message
news:59960632422914913133552@msnews.microsoft.com...
> 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
> > ======================================================================
> > ====== ====
> >
>
>