Problem :
I have to call some badly written 3rd party COM components that have memory leaks and uses Single Threaded Apartment [STA] within a long running process.
I know separate process will be nice way to implement it and I can restart it occasionally from the long running process.
Can AppDomain be used instead? Is AppDomain thread a STA thread if marked appropiately? Does it have its own memory for COM objects? Is unloading the AppDomain is equivalent of killing the process?
Solution :
An AppDomain does not provide the same degree of isolation as a process does. In fact if you’re worried that the 3rd party component is not in good shape there’s a risk, that it will take down your .NET application.
An AppDomain cannot be unloaded if unmanaged code is executing at the time of unload, so you may have a hard time controlling your 3rd party code in an AppDomain. See http://msdn.microsoft.com/en-us/library/system.appdomain.unload.aspx
Even for managed code only, an AppDomain does not provide a robust sandbox solution. E.g. if the loaded code spawns any threads these will take down the entire process in case of unhandled exceptions. This question has a bit more info: .NET – What’s the best way to implement a “catch all exceptions handler”.
As far as I am aware the best option for hosting code like that in a .NET application is to implement your own CLR host process like IIS and SQL Server does.
An AppDomain (application domain), is an isolated environment where applications execute.
They help provide isolation,
unloading, and security boundaries for
executing managed code.
Use application domains to isolate tasks that might bring down a process.
If the state of the AppDomain that’s
executing a task becomes unstable, the
AppDomain can be unloaded without
affecting the process. This is
important when a process must run for
long periods without restarting. You
can also use application domains to
isolate tasks that should not share
data.If an assembly is loaded into the default application domain, it cannot
be unloaded from memory while the
process is running. However, if you
open a second application domain to
load and execute the assembly, the
assembly is unloaded when that
application domain is unloaded. Use
this technique to minimize the working
set of long-running processes that
occasionally use large DLLs.Multiple application domains can run
in a single process; however, there is
not a one-to-one correlation between
application domains and threads.
Several threads can belong to a single
application domain, and while a given
thread is not confined to a single
application domain, at any given time,
a thread executes in a single
application domain.
SO Questions that might be of interest:
I won’t profess to be an expert in the area of AppDomains, but I am fairly sure that a COM object leaking memory (i.e. unmanaged memory) will not be freed by unloading the AppDomain. Perhaps someone more familiar with this could comment.
As Brian pointed out, “… in the .NET Framework version 2.0 domain is not guaranteed to unload, because it might not be possible to terminate executing threads. “