Skip to content

Commit

Permalink
Check if AppDomain is already unloaded before accessing. (#54)
Browse files Browse the repository at this point in the history
* Check if AppDomain is already unloaded before accessing.

Fixes #51

* Bump package release version to 1.1.13
  • Loading branch information
jthelin authored Oct 13, 2018
1 parent 413799a commit 2c5782d
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 10 deletions.
41 changes: 32 additions & 9 deletions ServerHost/ServerHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,14 @@ public static ServerHostHandle<TServer> LoadServerInNewAppDomain<TServer>(
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
public static void UnloadServerInAppDomain(AppDomain appDomain)
{
if (appDomain == null) return;
if (appDomain == null || appDomain.IsUnloaded()) return;

string appDomainName = "UNKNOWN";

try
{
// We may get AppDomainUnloadedException thrown here - X-ref: #46.

appDomainName = appDomain.FriendlyName;

appDomain.UnhandledException -= ReportUnobservedException;
Expand Down Expand Up @@ -138,20 +140,21 @@ public static void UnloadAllServers()
{
if (appDomain == null) continue;

string appDomainName = null;
try
if (appDomain.IsUnloaded())
{
// We may get AppDomainUnloadedException thrown here - X-ref: #46.

appDomainName = appDomain.FriendlyName;
Log.Debug($"AppDomain for server {serverName} has already been unloaded.");
continue;
}

Log.Info($"Unloading Server {serverName} in AppDomain {appDomainName}");
try
{
Log.Info($"Unloading AppDomain for server {serverName}.");

UnloadServerInAppDomain(appDomain);
}
catch (Exception exc)
{
Log.Warn($"Ignoring error unloading AppDomain {appDomainName ?? serverName}. " + exc.Message, exc);
Log.Warn($"Ignoring error unloading AppDomain for server {serverName}. " + exc.Message, exc);
}
}
}
Expand All @@ -161,7 +164,7 @@ public static void UnloadAllServers()
/// Construct AppDomain configuration metadata based on the current execution environment.
/// </summary>
/// <returns>AppDomainSetup info for creating an new child AppDomain.</returns>
private static AppDomainSetup GetAppDomainSetupInfo()
public static AppDomainSetup GetAppDomainSetupInfo()
{
AppDomain currentAppDomain = AppDomain.CurrentDomain;

Expand Down Expand Up @@ -190,5 +193,25 @@ private static void ReportUnobservedException(object sender, UnhandledExceptionE
Exception exception = (Exception) eventArgs.ExceptionObject;
Log.Warn("Unobserved exception: " + exception);
}

/// <summary>
/// Check whether the specified AppDomain has already been unloaded and is now inaccessible.
/// </summary>
/// <returns> Returns <c>true</c> if the specified AppDomain has been unloaded.</returns>
/// <param name="appDomain"> The AppDomain to be checked. </param>
private static bool IsUnloaded(this AppDomain appDomain)
{
try
{
string unused = appDomain.FriendlyName;

// If this worked, then the AppDomain is still accessible.
return false;
}
catch (AppDomainUnloadedException)
{
return true;
}
}
}
}
2 changes: 1 addition & 1 deletion ServerHost/ServerHost.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

<PropertyGroup>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Version>1.1.12</Version>
<Version>1.1.13</Version>
<Authors>Jorgen Thelin</Authors>
<Copyright>Copyright © Jorgen Thelin 2015-2018</Copyright>
<Description>ServerHost - A .NET Server Hosting utility library, including in-process server host testing.</Description>
Expand Down

0 comments on commit 2c5782d

Please sign in to comment.