I have some single-threaded code that uses C# reflection to load some global types and do some processing.
foreach (Assembly assembly in assemblies) { if (CheckAssembly(assembly)) { Type[] types = assembly.GetTypes(flags); foreach (Type type in types) if (CheckType(type)) DoWork(type); } }
The program was quite simple, and after got it working, I tried to multithreading it. I'm quite new to multithreading in general and C#, so I just used the standard Task library. There're a couple of ways I can do this: I can either run a new task for each of the assemblies, or for each of the types, or both.
foreach (Assembly assembly in assemblies) { if (CheckAssembly(assembly)) { // Assembly taskList.Add(Task.Run(() => { Type[] types = ...; foreach (Type type in types) ... })); // or Type Type[] types = assembly.GetTypes(flags); foreach (Type type in types) if (CheckType(type)) taskList.Add(Task.Run(() => DoWork(type))); } }
For some reason, having each task handle each assembly is faster than for each task to handle each type or both. This leads me to believe there's probably some lock contention happening for types in the same assembly. I couldn't find any article about how the C# reflection library handles threading or locking. The only thing I know is it thread-safe. Does anyone have any information about this?