private static void CloseAppDomain(int index)
{
AppDomain appDomain;
// Locking s_AppDomains must happen in a CER so we don't orphan a lock that gets taken by AppDomain.DomainUnload.
bool lockHeld = false;
RuntimeHelpers.PrepareConstrainedRegions();
try
{
try { }
finally
{
Monitor.Enter(s_AppDomains.SyncRoot);
lockHeld = true;
}
if (s_CleanedUp)
{
return;
}
appDomain = (AppDomain) s_AppDomains[index];
}
finally
{
if (lockHeld)
{
Monitor.Exit(s_AppDomains.SyncRoot);
lockHeld = false;
}
}
try
{
// Cannot call Unload() in a lock shared by OnDomainUnload() - deadlock with ADUnload thread.
// So we may try to unload the same domain twice.
AppDomain.Unload(appDomain);
}
catch (AppDomainUnloadedException) { }
finally
{
RuntimeHelpers.PrepareConstrainedRegions();
try
{
try { }
finally
{
Monitor.Enter(s_AppDomains.SyncRoot);
lockHeld = true;
}
s_AppDomains.Remove(index);
}
finally
{
if (lockHeld)
{
Monitor.Exit(s_AppDomains.SyncRoot);
}
}
}
}