使用AssemblyLoadContext从AssemblyPath加载后,无法在以后卸载它

huangapple go评论128阅读模式
英文:

Using AssemblyLoadContext LoadFromAssemblyPath fails to unload it later

问题

我正在在.NET 7 WPF应用程序中动态加载程序集。

此上下文加载器允许我稍后卸载它(参见 MemoryStream):
(取自此处:https://github.com/dotnet/runtime/issues/13226)

  1. public class CollectableAssemblyLoadContext : AssemblyLoadContext
  2. {
  3. private bool disposedValue;
  4. public CollectableAssemblyLoadContext(string name) : base(name, true) { }
  5. protected override Assembly Load(AssemblyName assemblyName) => null;
  6. public Assembly Load(byte[] rawAssembly)
  7. {
  8. using (var memoryStream = new MemoryStream(rawAssembly))
  9. {
  10. var assembly = LoadFromStream(memoryStream);
  11. return assembly;
  12. }
  13. }
  14. }

但是在卸载时会引发 "不可收集的程序集" 异常:
(取自此处:https://learn.microsoft.com/en-gb/dotnet/core/tutorials/creating-app-with-plugin-support)

  1. public class PluginLoader : AssemblyLoadContext
  2. {
  3. private AssemblyDependencyResolver resolver;
  4. public PluginLoader(string pluginPath)
  5. {
  6. resolver = new AssemblyDependencyResolver(pluginPath);
  7. }
  8. protected override Assembly Load(AssemblyName assemblyName)
  9. {
  10. string assemblyPath = resolver.ResolveAssemblyToPath(assemblyName);
  11. if (assemblyPath != null)
  12. {
  13. return LoadFromAssemblyPath(assemblyPath);
  14. }
  15. return null;
  16. }
  17. }

为什么会出现这个异常?是设计如此还是我做错了什么?

英文:

I am loading an assembly dynamically at run-time in .net 7 WPF app..

This context loader lets me to unload it later (see the MemoryStream):
(taken from here: https://github.com/dotnet/runtime/issues/13226)

  1. public class CollectableAssemblyLoadContext : AssemblyLoadContext
  2. {
  3. private bool disposedValue;
  4. public CollectableAssemblyLoadContext(string name) : base(name, true) { }
  5. protected override Assembly Load(AssemblyName assemblyName) => null;
  6. public Assembly Load(byte[] rawAssembly)
  7. {
  8. using (var memoryStream = new MemoryStream(rawAssembly))
  9. {
  10. var assembly = LoadFromStream(memoryStream);
  11. return assembly;
  12. }
  13. }
  14. }

And this throws "not collectible assembly" exception on unload:
(taken from here: https://learn.microsoft.com/en-gb/dotnet/core/tutorials/creating-app-with-plugin-support)

  1. public class PluginLoader : AssemblyLoadContext
  2. {
  3. private AssemblyDependencyResolver resolver;
  4. public PluginLoader(string pluginPath)
  5. {
  6. resolver = new AssemblyDependencyResolver(pluginPath);
  7. }
  8. protected override Assembly Load(AssemblyName assemblyName)
  9. {
  10. string assemblyPath = resolver.ResolveAssemblyToPath(assemblyName);
  11. if (assemblyPath != null)
  12. {
  13. return LoadFromAssemblyPath(assemblyPath);
  14. }
  15. return null;
  16. }
  17. }

Why? Is it by design or am I doing something wrong?

答案1

得分: 0

构造函数应该调用基类,并将标志设置为 true - 这确保了可收集性:

  1. public PluginLoader(string pluginPath) : base(pluginPath, true)
英文:

The constructor should call base class with flag set to true - that ensures collectability:

  1. public PluginLoader(string pluginPath) : base(pluginPath, true)

huangapple
  • 本文由 发表于 2023年7月17日 20:00:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/76704244.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定