Possible Buy/Issue with AppDomain.UnLoad

B

BuddyWork

I think I've found a possible issue with .Net AppDomain.Unload when
using attribute LoaderOptimization.MultiDomain.

Here you will need ProcessExplorer from SysInternals to see what
assemblies are loaded for a given process.

You will need to add the following code into HelloWorld1.cs and compile
through the CS compiler. csc HelloWorld1.cs

// C# Sample Code
// File: HelloWorld1.cs

using System;
using System.Threading;

public class HelloWorld
{
public void SayHello(String greeting)
{
Console.WriteLine("In the application domain: " +
Thread.GetDomain().FriendlyName);
Console.WriteLine(greeting);
}

public static void Main( String[] argv )
{
HelloWorld o = new HelloWorld();
o.SayHello("Hello World!");
}
}

You will need to add the following code into ExecAssembly.cs and
compile through the CS compiler. csc ExecAssembly.cs
// C# Sample Code
// File: ExecAssembly.cs
// Creates a remote application domain and executes an assembly
// within that application domain.

using System;
using System.Reflection;
using System.Runtime.Remoting;

public class ExecAssembly
{
// By un-commenting the line below causes the problem.
//[LoaderOptimization(LoaderOptimization.MultiDomain)]
public static void Main( String[] argv )
{
// Set ApplicationBase to the current directory
AppDomainSetup info = new AppDomainSetup();
info.ApplicationBase = "file:///" +
System.Environment.CurrentDirectory;

// Create an application domain with null evidence
AppDomain dom = AppDomain.CreateDomain("RemoteDomain", null, info);

// Tell the AppDomain to execute the assembly
dom.ExecuteAssembly("HelloWorld1.exe");

// Clean up by unloading the application domain
AppDomain.Unload(dom);
Console.WriteLine("HelloWorld1 UnLoaded");
int i = Console.Read ();
}
}

Now run the ExecAssembly.exe and while the message HelloWorld1.Unloaded
is displayed check through ProcessExplorer and you will notice the EXE
HelloWorld1.exe is not listed.

Now un-comment the line
[LoaderOptimization(LoaderOptimization.MultiDomain)] in module
ExecAssembly.cs and recompile the code. csc ExecAssembly.cs

Now run the ExecAssembly.exe and while the message HelloWorld1.Unloaded
is displayed check through ProcessExplorer and you will notice the EXE
HelloWorld1.exe now listed.

The problem is this the framework is not unloading the assembly because
its hold in the shared domain, I thought the shared domain would be
intelligent enough to know that no other domains are referencing the
assembly so it now removes it from the shared domain.

Can someone explain this to me.
 
W

Willy Denoyette [MVP]

This is by design, assemblies loaded as domain neutral in the "SharedDomain"
domain cannot be unloaded, and by applying the MultiDomainHost attribute,
you 'hint' the CLR to load all assemblies as domain neutral. All assemblies
loaded domain neutral cannot be unloaded even though all the appdomains
using these assemblies have been unloaded
Note also that there is no code execution in "SharedDomain", the code is
executed in user appdomains.

Willy.

BuddyWork said:
I think I've found a possible issue with .Net AppDomain.Unload when
using attribute LoaderOptimization.MultiDomain.

Here you will need ProcessExplorer from SysInternals to see what
assemblies are loaded for a given process.

You will need to add the following code into HelloWorld1.cs and compile
through the CS compiler. csc HelloWorld1.cs

// C# Sample Code
// File: HelloWorld1.cs

using System;
using System.Threading;

public class HelloWorld
{
public void SayHello(String greeting)
{
Console.WriteLine("In the application domain: " +
Thread.GetDomain().FriendlyName);
Console.WriteLine(greeting);
}

public static void Main( String[] argv )
{
HelloWorld o = new HelloWorld();
o.SayHello("Hello World!");
}
}

You will need to add the following code into ExecAssembly.cs and
compile through the CS compiler. csc ExecAssembly.cs
// C# Sample Code
// File: ExecAssembly.cs
// Creates a remote application domain and executes an assembly
// within that application domain.

using System;
using System.Reflection;
using System.Runtime.Remoting;

public class ExecAssembly
{
// By un-commenting the line below causes the problem.
//[LoaderOptimization(LoaderOptimization.MultiDomain)]
public static void Main( String[] argv )
{
// Set ApplicationBase to the current directory
AppDomainSetup info = new AppDomainSetup();
info.ApplicationBase = "file:///" +
System.Environment.CurrentDirectory;

// Create an application domain with null evidence
AppDomain dom = AppDomain.CreateDomain("RemoteDomain", null, info);

// Tell the AppDomain to execute the assembly
dom.ExecuteAssembly("HelloWorld1.exe");

// Clean up by unloading the application domain
AppDomain.Unload(dom);
Console.WriteLine("HelloWorld1 UnLoaded");
int i = Console.Read ();
}
}

Now run the ExecAssembly.exe and while the message HelloWorld1.Unloaded
is displayed check through ProcessExplorer and you will notice the EXE
HelloWorld1.exe is not listed.

Now un-comment the line
[LoaderOptimization(LoaderOptimization.MultiDomain)] in module
ExecAssembly.cs and recompile the code. csc ExecAssembly.cs

Now run the ExecAssembly.exe and while the message HelloWorld1.Unloaded
is displayed check through ProcessExplorer and you will notice the EXE
HelloWorld1.exe now listed.

The problem is this the framework is not unloading the assembly because
its hold in the shared domain, I thought the shared domain would be
intelligent enough to know that no other domains are referencing the
assembly so it now removes it from the shared domain.

Can someone explain this to me.
 

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