Unload assembly C#

L

Luis Pinho

Hi There,

I've got a server that is waiting for requests, these request
correspond to calls to objects that are specified in assemblies stored
in the GAC.

To do this, I use reflection to call the methods.

Now, when I'm trying to optimize the code, I noticed that the
assemblies that are loaded during the reflection call, are never
unloaded.

This is the current problem, the solution: AppDomain.

Using this I load everything in a new AppDomain and then just unload
it, in theory, no problems. When I try to do this, the problems start.

Based on the article written by Eric Gunnerson
(http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/csharp05162002.asp),
I've made something similar, but unfortunaly I got several problems.

Here's my code:


*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
object output1;
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationName = "SAP";
AppDomain domain = AppDomain.CreateDomain("SAP",null,setup);
try
{
Assembly assembly1 = domain.Load(assemblyName);

int i=0;
while (domain.GetAssemblies().FullName!=assemblyName)
i++;

Type invokerType1 = domain.GetAssemblies().GetType(className);
object objInvoker1 =
domain.CreateInstanceAndUnwrap(assemblyName,className);
invokerType1.GetProperty("Connection").SetValue(objInvoker1,SAPconn,
new object[0]);

output1 = invokerType1.InvokeMember(methodName,BindingFlags.InvokeMethod,null,
objInvoker1,args);

assembly1 = null;
objInvoker1 = null;
invokerType1 =null;

}
finally
{
AppDomain.Unload(domain);
}
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*

SAPconn is a object used to connect to a SAP server (not serializable)

When I try to run this I get the following exception:

System.Reflection.TargetInvocationException: Exception has been thrown
by the target of an invocation. --->
System.Runtime.Serialization.SerializationException: The type
SAP.Connector.SAPConnection in Assembly SAP.Connector,
Version=1.2.0.0, Culture=neutral, PublicKeyToken=50436dca5c7f7d23 is
not marked as serializable.

The error is thrown at the line:

invokerType1.GetProperty("Connection").SetValue(objInvoker1,SAPconn,
new object[0]);

If I use the same code, without using AppDomain (if I don't care that
the assemblies references don't disappear)

*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
object output;
Assembly assembly = Assembly.LoadWithPartialName(assemblyName);
Type invokerType = assembly.GetType(className);
object objInvoker = null;
objInvoker = Activator.CreateInstance(invokerType);
invokerType.GetProperty("Connection").SetValue(objInvoker,SAPconn, new
object[0]);
output = invokerType.InvokeMember(methodName,
BindingFlags.InvokeMethod,
null,
objInvoker,
args);

return output;
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*

Thanks for all the help,

Luís Pinho
 
P

Philip Rieck

Luis:

What you'll want to do is create an assembly that you can have your new
appdomain load up - in this assembly, you have the functionality to use
reflection to invoke a method. Then from your static appdomain, call into
this type, which will actually do the work. This will keep you from having
to serialize 3rd party types between appdomains (which may also require
assembly loading into the default domain)

psuedocode
<In main appdomain>
{
Create AppDomain "domain"
Call "domain.load" loading type "shim"
Call shim's "MyInvokeMethod(typename, methodname)
Unload "domain"
}

<in "shim", which is loaded into new appdomain>
MyInvokeMethod(typename, methodname)
{
Load assembly based on typename
Instantiate new typename
call methodname
return
}


Luis Pinho said:
Hi There,

I've got a server that is waiting for requests, these request
correspond to calls to objects that are specified in assemblies stored
in the GAC.

To do this, I use reflection to call the methods.

Now, when I'm trying to optimize the code, I noticed that the
assemblies that are loaded during the reflection call, are never
unloaded.

This is the current problem, the solution: AppDomain.

Using this I load everything in a new AppDomain and then just unload
it, in theory, no problems. When I try to do this, the problems start.

Based on the article written by Eric Gunnerson
(http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/ht
ml/csharp05162002.asp),
I've made something similar, but unfortunaly I got several problems.

Here's my code:


*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
*
object output1;
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationName = "SAP";
AppDomain domain = AppDomain.CreateDomain("SAP",null,setup);
try
{
Assembly assembly1 = domain.Load(assemblyName);

int i=0;
while (domain.GetAssemblies().FullName!=assemblyName)
i++;

Type invokerType1 = domain.GetAssemblies().GetType(className);
object objInvoker1 =
domain.CreateInstanceAndUnwrap(assemblyName,className);
invokerType1.GetProperty("Connection").SetValue(objInvoker1,SAPconn,
new object[0]);

output1 = invokerType1.InvokeMember(methodName,BindingFlags.InvokeMethod,null,
objInvoker1,args);

assembly1 = null;
objInvoker1 = null;
invokerType1 =null;

}
finally
{
AppDomain.Unload(domain);
}
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
*

SAPconn is a object used to connect to a SAP server (not serializable)

When I try to run this I get the following exception:

System.Reflection.TargetInvocationException: Exception has been thrown
by the target of an invocation. --->
System.Runtime.Serialization.SerializationException: The type
SAP.Connector.SAPConnection in Assembly SAP.Connector,
Version=1.2.0.0, Culture=neutral, PublicKeyToken=50436dca5c7f7d23 is
not marked as serializable.

The error is thrown at the line:

invokerType1.GetProperty("Connection").SetValue(objInvoker1,SAPconn,
new object[0]);

If I use the same code, without using AppDomain (if I don't care that
the assemblies references don't disappear)

*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
*
object output;
Assembly assembly = Assembly.LoadWithPartialName(assemblyName);
Type invokerType = assembly.GetType(className);
object objInvoker = null;
objInvoker = Activator.CreateInstance(invokerType);
invokerType.GetProperty("Connection").SetValue(objInvoker,SAPconn, new
object[0]);
output = invokerType.InvokeMember(methodName,
BindingFlags.InvokeMethod,
null,
objInvoker,
args);

return output;
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
*

Thanks for all the help,

Luís Pinho
 

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