Preloading assemblies into an AppDomain I create

I

illegal.prime

Hi all, I'm getting unexpected results when trying to preload
assemblies into an AppDomain I'm creating. Upon creation of the
AppDomain - I attach an AssemblyResolve to both my current AppDomain
and the new AppDomain I create.

I copy all the assemblies/dlls into a new directory and then try
loading them all into the new AppDomain using the following:

private void LoadAssembliesFromDirectory(AppDomain appDomain, string
directory)
{
DirectoryInfo dirInfo = new DirectoryInfo(directory);
foreach (FileInfo fileInfo in dirInfo.GetFiles("*.dll"))
{
try
{
Assembly assembly = Assembly.LoadFrom(fileInfo.FullName);
// Is there a better property we could be handing the Load method
other than the FullName of the assembly?
//appDomain.Load(assembly.FullName);
// The following will hopefully work better
byte[] assemblyByteArray = File.ReadAllBytes(fileInfo.FullName);
Assembly loadedAssembly = appDomain.Load(assemblyByteArray);
}
catch (Exception exception)
{

Trace.WriteLine("LoadAssembliesFromDirectory.LoadAssembliesFromDirectory:
could not load: " + fileInfo.FullName);

Trace.WriteLine("LoadAssembliesFromDirectory.LoadAssembliesFromDirectory:
exception: " + exception.Message);
}
}
}

Oddly enough the AssemblyResolver that ends up getting invoked is the
AssemblyResolver for the current AppDomain - not the new AppDomain
I've created (and whose reference I've passed into the above method).

The above all works and I can start my application using the
AppDomain.ExecuteAssemblyByName. However, it is slower doing the
above (rather than just executing the executable from the command-
line). I can see that the assemblies aren't being loaded in the way
they were before - so not sure why it is slower.

I've heard that remoting is used to pass the assemblies into the new
AppDomain - is that why things are slower? Is there something I could
be doing to make this new approach faster? Or will this approach
always be slower?

Novice
 
I

illegal.prime

Thanks Brian - I've updated my code to use get a serializable object
that I get from the AppDomain. I then preload those assemblies into
that AppDomain - but I'm still seeing slower performance. Just to re-
emphasize - I don't care how long it takes to preload all the
assemblies into the AppDomain (nor to be honest whether they are
loaded into any other AppDomain). But then when I execute the
application it is slower than if I had just executed it from the
command-line. Does anyone know if it is possible to preload
assemblies into an AppDomain and then actually recognize a speed-up as
a result?

I suppose my next step will be to add some profiling to my application
to see where the new hot spots are... but intuitively I would've
expected preloading assemblies to be quicker than not. In fact I
would expect this to be one of the primary benefits of using
AppDomains.

Thanks,
Novice

The instance method is strange as it actually loads your assembly in the
current domain as well. Check the documentation:http://msdn.microsoft.com/en-us/library/36az8x58.aspx it's documented, but
odd.

--
Regards,
Brian Rasmussen [C# MVP]http://kodehoved.dk




Hi all, I'm getting unexpected results when trying to preload
assemblies into an AppDomain I'm creating.  Upon creation of the
AppDomain - I attach an AssemblyResolve to both my current AppDomain
and the new AppDomain I create.
I copy all the assemblies/dlls into a new directory and then try
loading them all into the new AppDomain using the following:
private void LoadAssembliesFromDirectory(AppDomain appDomain, string
directory)
{
DirectoryInfo dirInfo = new DirectoryInfo(directory);
foreach (FileInfo fileInfo in dirInfo.GetFiles("*.dll"))
{
try
{
Assembly assembly = Assembly.LoadFrom(fileInfo.FullName);
// Is there a better property we could be handing the Load method
other than the FullName of the assembly?
//appDomain.Load(assembly.FullName);
// The following will hopefully work better
byte[] assemblyByteArray = File.ReadAllBytes(fileInfo.FullName);
Assembly loadedAssembly = appDomain.Load(assemblyByteArray);
}
catch (Exception exception)
{
Trace.WriteLine("LoadAssembliesFromDirectory.LoadAssembliesFromDirectory:
could not load: " + fileInfo.FullName);
Trace.WriteLine("LoadAssembliesFromDirectory.LoadAssembliesFromDirectory:
exception: " + exception.Message);
}
}
}
Oddly enough the AssemblyResolver that ends up getting invoked is the
AssemblyResolver for the current AppDomain - not the new AppDomain
I've created (and whose reference I've passed into the above method).
The above all works and I can start my application using the
AppDomain.ExecuteAssemblyByName.  However, it is slower doing the
above (rather than just executing the executable from the command-
line).  I can see that the assemblies aren't being loaded in the way
they were before - so not sure why it is slower.
I've heard that remoting is used to pass the assemblies into the new
AppDomain - is that why things are slower?  Is there something I could
be doing to make this new approach faster?  Or will this approach
always be slower?
Novice- Hide quoted text -

- Show quoted text -
 
J

Jeff Winn

Unless you're actually using one of the Assembly.Load methods from within
the remote appdomain they're going to be loaded by the current appdomain.
You could create and unwrap an instance of an MBRO object in your remote
appdomain (using remoting) and tell it to load the assemblies. That would
ensure the current domain does not load anything.

If you absolutely need access to the assembly information in your primary
appdomain use AssemblyRef. That will give you information about the assembly
without actually loading it into the current appdomain.

Is there any particular reason why you're needing to resolve assembly
locations? Only reason I can think of is if you're trying to load assemblies
outside of the probing path for your appdomain, or you haven't set the
probing path.

Thanks Brian - I've updated my code to use get a serializable object
that I get from the AppDomain. I then preload those assemblies into
that AppDomain - but I'm still seeing slower performance. Just to re-
emphasize - I don't care how long it takes to preload all the
assemblies into the AppDomain (nor to be honest whether they are
loaded into any other AppDomain). But then when I execute the
application it is slower than if I had just executed it from the
command-line. Does anyone know if it is possible to preload
assemblies into an AppDomain and then actually recognize a speed-up as
a result?

I suppose my next step will be to add some profiling to my application
to see where the new hot spots are... but intuitively I would've
expected preloading assemblies to be quicker than not. In fact I
would expect this to be one of the primary benefits of using
AppDomains.

Thanks,
Novice

The instance method is strange as it actually loads your assembly in the
current domain as well. Check the
documentation:http://msdn.microsoft.com/en-us/library/36az8x58.aspx it's
documented, but
odd.

--
Regards,
Brian Rasmussen [C# MVP]http://kodehoved.dk




Hi all, I'm getting unexpected results when trying to preload
assemblies into an AppDomain I'm creating. Upon creation of the
AppDomain - I attach an AssemblyResolve to both my current AppDomain
and the new AppDomain I create.
I copy all the assemblies/dlls into a new directory and then try
loading them all into the new AppDomain using the following:
private void LoadAssembliesFromDirectory(AppDomain appDomain, string
directory)
{
DirectoryInfo dirInfo = new DirectoryInfo(directory);
foreach (FileInfo fileInfo in dirInfo.GetFiles("*.dll"))
{
try
{
Assembly assembly = Assembly.LoadFrom(fileInfo.FullName);
// Is there a better property we could be handing the Load method
other than the FullName of the assembly?
//appDomain.Load(assembly.FullName);
// The following will hopefully work better
byte[] assemblyByteArray = File.ReadAllBytes(fileInfo.FullName);
Assembly loadedAssembly = appDomain.Load(assemblyByteArray);
}
catch (Exception exception)
{
Trace.WriteLine("LoadAssembliesFromDirectory.LoadAssembliesFromDirectory:
could not load: " + fileInfo.FullName);
Trace.WriteLine("LoadAssembliesFromDirectory.LoadAssembliesFromDirectory:
exception: " + exception.Message);
}
}
}
Oddly enough the AssemblyResolver that ends up getting invoked is the
AssemblyResolver for the current AppDomain - not the new AppDomain
I've created (and whose reference I've passed into the above method).
The above all works and I can start my application using the
AppDomain.ExecuteAssemblyByName. However, it is slower doing the
above (rather than just executing the executable from the command-
line). I can see that the assemblies aren't being loaded in the way
they were before - so not sure why it is slower.
I've heard that remoting is used to pass the assemblies into the new
AppDomain - is that why things are slower? Is there something I could
be doing to make this new approach faster? Or will this approach
always be slower?
Novice- Hide quoted text -

- Show quoted text -
 
I

illegal.prime

Hmm... actually my objective is quite simple. I just want to create
an application (application A) to launch another application
(application B). I want application A to preload the assemblies for
application B (by using the AppDomain functionality). When I found
out about AppDomains I figured they would allow you to preload the
assemblies for an application and thus make that application start-up
quicker than if you just started it from the command-line. Perhaps my
assumption was incorrect. Does anyone know whether that is
achieveable?

As for your specific questions. I was previously using AppDomain.Load
to load assemblies into application B's AppDomain. As you suggest -
this results in the assembly being loaded into both application A and
application B's AppDomain. However, at this point this isn't a show-
stopper - since it isn't part of my objective - I can look at refining
the work-flow later if I find this to be an issue for some reason. In
any case, I went ahead and used AppDomain.CreateInstanceAndUnwrap to
see if using the object from application B's AppDomain to load the
assemblies would work any better. This had no effect on performance -
it was still slower to launch application B from application A -
rather than just to execute application B directly. The only effect
was that application A's AssemblyResolve handler no longer seemed to
be getting executed.

Novice

Unless you're actually using one of the Assembly.Load methods from within
the remote appdomain they're going to be loaded by the current appdomain.
You could create and unwrap an instance of an MBRO object in your remote
appdomain (using remoting) and tell it to load the assemblies. That would
ensure the current domain does not load anything.

If you absolutely need access to the assembly information in your primary
appdomain use AssemblyRef. That will give you information about the assembly
without actually loading it into the current appdomain.

Is there any particular reason why you're needing to resolve assembly
locations? Only reason I can think of is if you're trying to load assemblies
outside of the probing path for your appdomain, or you haven't set the
probing path.


Thanks Brian - I've updated my code to use get a serializable object
that I get from the AppDomain.  I then preload those assemblies into
that AppDomain - but I'm still seeing slower performance.  Just to re-
emphasize - I don't care how long it takes to preload all the
assemblies into the AppDomain (nor to be honest whether they are
loaded into any other AppDomain).  But then when I execute the
application it is slower than if I had just executed it from the
command-line.  Does anyone know if it is possible to preload
assemblies into an AppDomain and then actually recognize a speed-up as
a result?

I suppose my next step will be to add some profiling to my application
to see where the new hot spots are... but intuitively I would've
expected preloading assemblies to be quicker than not.  In fact I
would expect this to be one of the primary benefits of using
AppDomains.

Thanks,
Novice

The instance method is strange as it actually loads your assembly in the
current domain as well. Check the
documentation:http://msdn.microsoft.com/en-us/library/36az8x58.aspxit's
documented, but
odd.
Hi all, I'm getting unexpected results when trying to preload
assemblies into an AppDomain I'm creating. Upon creation of the
AppDomain - I attach an AssemblyResolve to both my current AppDomain
and the new AppDomain I create.
I copy all the assemblies/dlls into a new directory and then try
loading them all into the new AppDomain using the following:
private void LoadAssembliesFromDirectory(AppDomain appDomain, string
directory)
{
DirectoryInfo dirInfo = new DirectoryInfo(directory);
foreach (FileInfo fileInfo in dirInfo.GetFiles("*.dll"))
{
try
{
Assembly assembly = Assembly.LoadFrom(fileInfo.FullName);
// Is there a better property we could be handing the Load method
other than the FullName of the assembly?
//appDomain.Load(assembly.FullName);
// The following will hopefully work better
byte[] assemblyByteArray = File.ReadAllBytes(fileInfo.FullName);
Assembly loadedAssembly = appDomain.Load(assemblyByteArray);
}
catch (Exception exception)
{
Trace.WriteLine("LoadAssembliesFromDirectory.LoadAssembliesFromDirectory:
could not load: " + fileInfo.FullName);
Trace.WriteLine("LoadAssembliesFromDirectory.LoadAssembliesFromDirectory:
exception: " + exception.Message);
}
}
}
Oddly enough the AssemblyResolver that ends up getting invoked is the
AssemblyResolver for the current AppDomain - not the new AppDomain
I've created (and whose reference I've passed into the above method).
The above all works and I can start my application using the
AppDomain.ExecuteAssemblyByName. However, it is slower doing the
above (rather than just executing the executable from the command-
line). I can see that the assemblies aren't being loaded in the way
they were before - so not sure why it is slower.
I've heard that remoting is used to pass the assemblies into the new
AppDomain - is that why things are slower? Is there something I could
be doing to make this new approach faster? Or will this approach
always be slower?
Novice- Hide quoted text -
- Show quoted text -- Hide quoted text -

- Show quoted text -
 

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