I have native unmanaged dll which is static and must be loaded each time when I need library to do some work if i want to run it in parallel. In .NET I would use AppDomain and load this dll when i need it, but in NET Core AppDomains are gone (for now). I have looked at AssemblyLoadContext but there is no proper documentation with LoadUnmanagedDll. Can this be done in netstandard1.6?
Edit
Currently code is called with PInvoke and is working perfectly. Problem is because nature of this unmanged dll, when I try to call it in parallel throws AccessViolationException because two or more task wants to access same memory.
If I could load dll for each time that in some context and then call PInvoke on that this problem would be gone.
One approach:
- Derive class from
System.Runtime.Loader.AssemblyLoadContext
- Override
Load(AssemblyName assemblyName)
calling LoadFromAssemblyPath()
or returning null to fallback on default context
- Override
IntPtr LoadUnmanagedDll(string unmanagedDllName)
calling LoadUnmanagedDllFromPath()
to load your native dll
- Indirectly access your pinvoke methods and load the native/unmanaged library through some known
interface
Step 4 is the part you need to adjust based on the structure of the existing code. In my case, I created 3 assemblies:
- Calling code
- Pinvoke code
- Interfaces shared by the first two
In the calling code:
var assem = assemblyLoadContext.LoadFromAssemblyName(new
System.Reflection.AssemblyName(pinvokeAssemblyName));
var type = assem.GetType(nameOfTypeThatCallsPinvoke);
return (ISharedInterface)Activator.CreateInstance(type);
When instance of nameOfTypeThatCallsPinvoke
attempts to use pinvoke method your LoadUnmanagedDll()
override on the load context will get called.
The shared interfaces are needed so types are known at compile-time. If the calling code references the pinvoke library directly it's types will differ from those obtained through the load context.
References:
- AssemblyLoadContext design doc
- Post about using AssemblyLoadContext to load plugins (code on github)
- Post about using AssemblyLoadContext with a native library (code on github) (Disclaimer: mine)