AppDomain.Unload() hangs

J

John Price

I'm writing a Windows Service that loads and manages a number of
"sub-services". Each sub-service implements a simple interface
(start(), stop()) and gets loaded into its own AppDomain. There is
also a client interface that allows an administrator to connect to the
service using remoting and start and stop sub-services without having
to restart the whole thing. All of this is with v1.1 of the framework.

When a sub-service is shutdown, I do a call to AppDomain.Unload() to
clear everything out and get a fresh start. Unfortunately,
AppDomain.Unload() seems to be finnicky and depending on how I do what
would seem to be entirely unrelated things, it can consistently hang.
I've seen other people reporting similar problems in newsgroups, but I
haven't seen anything that seems to explain what I'm seeing.

I was at first just having problems with the service itself. When I
tried to unload the appdomains on server shutdown in the main
application thread, AppDomain.Unload() would completely hang. Through
some experimentation, I discovered that if I instead performed the same
operations in a new thread, calls to AppDomain.Unload() return no
problem and everything works fine. So now I've got a pretty useless
extra thread, but it works.

Now I'm having an issue with the client. When I initialize remoting
programmatically in the server, connect with my client, and instruct
the server to shut down a particular sub-service, things work fine. If
instead I initialize remoting through a configuration file,
AppDomain.Unload() hangs when the client tries to stop the sub-service.
As far as I can tell, my two remoting configurations should be the
same:

BinaryServerFormatterSinkProvider serverProv = new
BinaryServerFormatterSinkProvider();
serverProv.TypeFilterLevel =
System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;

BinaryClientFormatterSinkProvider clientProv = new
BinaryClientFormatterSinkProvider();

IDictionary props = new Hashtable();
props["port"] = 1234;

TcpChannel chan = new TcpChannel( props, clientProv, serverProv );

ChannelServices.RegisterChannel( chan );
RemotingConfiguration.RegisterWellKnownServiceType(
typeof( MyType ),
"MyUri",
WellKnownObjectMode.Singleton );

Versus:

<system.runtime.remoting>
<application name="MyApplication">
<channels>
<channel ref="tcp" port="1234">
<serverProviders>
<formatter ref="binary" typeFilterLevel="Full"/>
</serverProviders>
<clientProviders>
<formatter ref="binary"/>
</clientProviders>
</channel>
</channels>
<service>
<wellknown mode="Singleton"
type="MyType, MyAssembly"
objectUri="MyUri"/>
</service>
</application>
</system.runtime.remoting>

At this point, I have absolutely no clue what causes AppDomain.Unload()
to hang, since the two fixes I've found seem entirely unrelated. I've
also tried simplifying the entire thing to the point that I could post
my code, but the problem only seems to arise once both my service
manager and my individual sub-services reach a certain level of
complexity. For trivial services, or a trivial service manager,
AppDomain.Unload() always seems to work.

Does anyone have any idea what might be causing AppDomain.Unload() to
not return? I'm not too desparate at the moment since I've got work
arounds for the cases I've run into, but it's a little scary to wonder
if every seemingly unrelated change I make could reintroduce the
problem.

John.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top