|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Generating code in a different AppDomainI've got a working project which runs as a service, and performs various simple calculations based on data provided to it in a database. Other data within the database describes the operations which must be performed on the data. (Essentially, there is a table called DataItemCalculations, that for each DataItem that is to be computed, has a sequence of instructions to a basic stack machine). At present, the service interprets the operations it must perform. It also can compile each calculation into a function (essentially running the interpreter, but emitting CodeDom elements instead of actually performing the requested operations). All is good. Once the compiled version is available, the service starts using this instead of interpreting. However, there is one issue that I am aware of. The service monitors it's calculations table for changes. If a change occurs, it dumps it's cached version of all of the calculations (and the compiled versions) and reloads them from the database. But because my compiled calculations are in the main AppDomain, they lurk around and represent a memory leak if the contents of the calculations table change frequently. What I would like to do is to place my compiled code into a separate AppDomain, that can be Unloaded at the same time as the caches are cleared, thus freeing the memory. Does anyone have some sample code of doing in memory compilation in a separate AppDomain? I believe I can build the CodeDom elements in my AppDomain and then pass them across, since they all seem to be marked as Serializable. I've already changed my compilation so that the created classes inherit from MarshalByRefObject, but I'm just finding a gap in the mental leap to generating in an alternate AppDomain. Damien (Existing compilation code. ccu is the CodeCompileUnit. CompiledDIC is an interface which the created class implements, BIL.CompiledDICs is the namespace) Dim vbp As New Microsoft.VisualBasic.VBCodeProvider Dim comp As Compiler.ICodeCompiler = vbp.CreateCompiler() Dim opts As New Compiler.CompilerParameters opts.GenerateInMemory = True Dim res As Compiler.CompilerResults = comp.CompileAssemblyFromDom(opts, ccu) If res.Errors.HasErrors Then Throw New StackMachine.StackMachineException(StackMachine.ExceptionCauses.BadProgram, "CompileDIC (OnCompile)") End If Return CType(res.CompiledAssembly.CreateInstance("BIL.CompiledDICs." & di.Name.Replace("."c, "_"c)), CompiledDIC) Hello, Damien!
Have a look at ( http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/csharp05162002.asp ) Rcik Strahl wrote a greta article on dynamic code generation...
http://www.west-wind.com/presentations/dynamicCode/DynamicCode.htm it inlcudes complete examples of doing this. Cheers, Greg Young MVP - C# http://codebetter.com/blogs/gregyoung Show quote "Damien" <Damien_The_Unbelie***@hotmail.com> wrote in message news:1154685389.949962.182950@h48g2000cwc.googlegroups.com... > Hi guys, > > I've got a working project which runs as a service, and performs > various simple calculations based on data provided to it in a database. > Other data within the database describes the operations which must be > performed on the data. (Essentially, there is a table called > DataItemCalculations, that for each DataItem that is to be computed, > has a sequence of instructions to a basic stack machine). > > At present, the service interprets the operations it must perform. It > also can compile each calculation into a function (essentially running > the interpreter, but emitting CodeDom elements instead of actually > performing the requested operations). All is good. Once the compiled > version is available, the service starts using this instead of > interpreting. > > However, there is one issue that I am aware of. The service monitors > it's calculations table for changes. If a change occurs, it dumps it's > cached version of all of the calculations (and the compiled versions) > and reloads them from the database. But because my compiled > calculations are in the main AppDomain, they lurk around and represent > a memory leak if the contents of the calculations table change > frequently. > > What I would like to do is to place my compiled code into a separate > AppDomain, that can be Unloaded at the same time as the caches are > cleared, thus freeing the memory. > > Does anyone have some sample code of doing in memory compilation in a > separate AppDomain? I believe I can build the CodeDom elements in my > AppDomain and then pass them across, since they all seem to be marked > as Serializable. I've already changed my compilation so that the > created classes inherit from MarshalByRefObject, but I'm just finding a > gap in the mental leap to generating in an alternate AppDomain. > > Damien > > (Existing compilation code. ccu is the CodeCompileUnit. CompiledDIC is > an interface which the created class implements, BIL.CompiledDICs is > the namespace) > > Dim vbp As New Microsoft.VisualBasic.VBCodeProvider > Dim comp As Compiler.ICodeCompiler = vbp.CreateCompiler() > Dim opts As New Compiler.CompilerParameters > opts.GenerateInMemory = True > Dim res As Compiler.CompilerResults = > comp.CompileAssemblyFromDom(opts, ccu) > If res.Errors.HasErrors Then > Throw New > StackMachine.StackMachineException(StackMachine.ExceptionCauses.BadProgram, > "CompileDIC (OnCompile)") > End If > > Return > CType(res.CompiledAssembly.CreateInstance("BIL.CompiledDICs." & > di.Name.Replace("."c, "_"c)), CompiledDIC) > Greg Young wrote:
> Rcik Strahl wrote a greta article on dynamic code generation... That looks kindof like what I'm after (he states that you have to hit> http://www.west-wind.com/presentations/dynamicCode/DynamicCode.htm it > inlcudes complete examples of doing this. > > Cheers, > > Greg Young > MVP - C# > http://codebetter.com/blogs/gregyoung > Hi Greg, the disk, or run the whole compilation in the other AppDomain, which I think is the path I'll be going down). I guess I'll just have to give it a go. Damien PS - Though not really what I was after, the link Vadym sent was also quite interesting, so cheers there too. |
|||||||||||||||||||||||