내 응용 프로그램이 실행될 때 유형이 추가되는 동적 모듈이 있습니다. 모듈은 다음 코드를 통해 생성됩니다.언제 동적 모듈에 유형로드 예외가있을 수 있습니까?
var assemblyName = new AssemblyName("MyAssembly");
var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
MyClass.RuntimeBoundDerivedTypesModule = assemblyBuilder.DefineDynamicModule("MainModule");
때때로 모듈 어셈블리에서 GetTypes()를 호출하는 경우가 있습니다. 가끔 이런 일이 발생하면 동적 모듈의 유형 중 하나에 대해 TypeLoadException이 발생합니다. 스택 추적은 다음과 같습니다.
at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module)
at System.Reflection.RuntimeModule.GetTypes()
at System.Reflection.Assembly.GetTypes()
제 질문은 :이 예외의 원인은 무엇입니까? 런타임 모듈은 실제로 스레드로부터 안전합니까? 또는 유형이 생성되는 동안 GetTypes()가 호출되는 경쟁 조건이있을 수 있습니까?
편집 : 다음은 나를 위해 버그를 확실하게 재현하는 작은 코드 단편입니다.
var assemblyName = new AssemblyName("MyAssembly");
var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
ModuleBuilder m = assemblyBuilder.DefineDynamicModule("foo");
Action doStuff =() => {
try {
if (!m.GetTypes().Any() || Guid.NewGuid().GetHashCode() % 2 == 0) {
var t = m.DefineType(
"MyType" + Guid.NewGuid().ToString().Replace("-", ""),
TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout,
typeof(object)
);
Thread.Sleep(1);
t.CreateType();
}
else {
//m.GetTypes(); // interestingly, this always works
assemblyBuilder.GetTypes();
"it worked!".Dump();
}
} catch (Exception ex) {
Console.WriteLine(ex);
}
};
// in synchronous mode, I only see failures if I leave out the call to CreateType(). In that
// case, it never works
//Enumerable.Range(1, 1000)
// .ToList()
// .ForEach(_ => doStuff());
// in the async mode, I always see failures with Thread.Sleep() and sometimes
// see them if I take the sleep out. I often see a mix of failures and "It worked!"
var threads = Enumerable.Range(1, 100).Select(t => new Thread(() => doStuff()))
.ToList();
threads.ForEach(t => t.Start());
threads.ForEach(t => t.Join());