![](/img/trans.png)
[英]Dynamically loading and unloading a a dll generated using CSharpCodeProvider
[英]Loading and then Unloading DLL with dependency locks the DLL
動態加載具有依賴關系的 DLL 然后卸載它,仍然鎖定 DLL,我無法刪除/替換 dll。
作為編寫插件應用程序的一部分,我動態加載 DLL(它具有依賴項,例如 Newtonsoft.Json),運行加載的程序集,然后將其卸載。 卸載后,我無法從磁盤中刪除 DLL(直到我重新啟動我的應用程序),但是,如果我使用沒有依賴關系的 DLL,它可以正常工作,並且不會鎖定文件。 該實現基於 .NET 核心 3 加載/卸載,取自: https://docs.microsoft.com/en-us/dotnet/standard/assembly/unloadability
我使用具有解析器的AssemblyLoadContext
,例如:
class TestAssemblyLoadContext : AssemblyLoadContext
{
private AssemblyDependencyResolver _resolver;
public TestAssemblyLoadContext(string mainAssemblyToLoadPath) : base(isCollectible: true)
{
_resolver = new AssemblyDependencyResolver(mainAssemblyToLoadPath);
}
protected override Assembly Load(AssemblyName name)
{
string assemblyPath = _resolver.ResolveAssemblyToPath(name);
if (assemblyPath != null)
{
return LoadFromAssemblyPath(assemblyPath);
}
return null;
}
}
以及創建上下文的代碼:
[MethodImpl(MethodImplOptions.NoInlining)]
public static void runCommands(string pluginPath, bool execute,out WeakReference alcWeakRef)
{
string pluginLocation = getPath(pluginPath);
PluginLoadContext loadContext = new PluginLoadContext(pluginLocation);
alcWeakRef = new WeakReference(loadContext, trackResurrection: true);
Assembly pluginAssembly = loadContext.LoadFromAssemblyName(new AssemblyName(Path.GetFileNameWithoutExtension(pluginLocation)));
var commands = CreateCommands(pluginAssembly).ToList();
if (execute) {
Console.WriteLine("Commands: ");
foreach (ICommand command in commands)
{
Console.WriteLine($"executing... {command.Execute()}");
}
}
commands.Clear();
loadContext.Unload();
}
如果這是我做錯的事情,我會徘徊,我已經嘗試從 stream 加載文件,例如:
using (var fs = new FileStream(pluginLocation, FileMode.Open, FileAccess.Read))
{
var pluginAssembly = loadContext.LoadFromStream(fs);
....
....
}
問題解決了,基本上在卸載 DLL 時,如果您有 Newtonsoft.Json 依賴項,則無法執行此操作,因為它們有一個鎖定文件的錯誤。
這是基於我打開的github 問題的響應
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.