I am attaching to the AppDomain.AssemblyResolve event and then calling Assembly.Load(byte[]) to load the assembly.
It seems that if this is done from multiple Threads I can end up with duplicate assemblies loaded. However if I call Assembly.LoadFrom or Assembly.LoadFile this problem does not occur.
I was just wondering if this is a known qwerk of using Assembly.Load? Is it not thread safe and I need to add extra code to handle this scenario?
Full code follows…
[TestFixture]
public class Tester
{
[Test]
public void Run()
{
var currentDomain = AppDomain.CurrentDomain;
currentDomain.AssemblyResolve += ResolveAssembly;
var thread1 = new Thread(LoadAssembly);
var thread2 = new Thread(LoadAssembly);
thread1.Start();
thread2.Start();
thread1.Join();
thread2.Join();
var assemblies = currentDomain.GetAssemblies();
Assert.AreEqual(1, assemblies.Count(x => x.GetName().Name == "AssemblyToReference"));
}
Assembly ResolveAssembly(object sender, ResolveEventArgs args)
{
//This works
//return Assembly.LoadFile(@"PathToAssembly");
//This works
//return Assembly.LoadFrom(@"PathToAssembly");
//This does not work
return Assembly.Load(File.ReadAllBytes(@"PathToAssembly"));
}
void LoadAssembly()
{
Assembly.Load("AssemblyToReference");
}
}
Looking at the implementation details of these methods you can make the case that the LoadFrom and LoadFile methods, since they are using the filesystem, have their synchronization there. That is, both methods get an exclusive lock on the file prior to reading it in. This of course is not the case with the assembly residing in memory.
(And MSDN has no statement of these methods being thread safe, perhaps that says enough? :))