WPF and AppDomains
In my earlier blog I had talked about how to work with AppDomains and the issues I had faced. I had a chance to interact with Hua Wang from Microsoft and it was very enlightening.
There are specific things that need to be taken care when creating and destroying AppDomains in WPF. .NET framework 3.0 supports new APIs for this purpose and these are to account for the threading model of WPF.
WPF uses the concept of Dispatcher. The UI work is managed via the dispatcher and all work/messages are handled by it.
When a new AppDomain is created, a new dispatcher is also created for it. Before we can shut down the AppDomain, we will also need to shut down the dispatcher. The AppDomain.Unload causes Thread.Abort in that domain and during the call the CLR tries to abort all threads. The Dispatcher thread is in the native mode and hence the CLR cannot abort it. It gives a few retries and then raises a CannotUnloadAppDomainException.
Suprisingly, in my initial testing, the AppDomain unload happened without a need to shutdown the dispatcher when i was using WPF extensions on VS2005. When I played around with Orcas Beta 1, I could see the exception getting raised.
The suggested solution is something like below
if (ad != null)
{
//Time to unload the app domain, but first shut down the dispatcher
ad.DoCallBack(new CrossAppDomainDelegate(ShutDown));
AppDomain.Unload(ad);
ad = null;
}
static void ShutDown()
{
Application.Current.Dispatcher.InvokeShutdown();
}
In the code above "ad" is the variable that stores the AppDomain that was created using AppDomain.CreateDomain. This solution is bound to work and I have tried it on VS 2008 (Orcas) Beta 2 as well