D
Damien
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)
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)