简体   繁体   English

卸载 AssemblyLoadContext.Net 6 核心抛出异常`System.ExecutionEngineException`

[英]Unloading AssemblyLoadContext .Net 6 Core throws Exception `System.ExecutionEngineException`

I wrote a simplistic plugin manager which works when creating a plugin instance and unloading it right away.我编写了一个简单的插件管理器,它在创建插件实例并立即卸载它时工作。 But when the plugin instance creation and unloading is done from different methods it throws the following exception without any further information:但是,当插件实例的创建和卸载是通过不同的方法完成时,它会抛出以下异常而没有任何进一步的信息:

"Exception of type 'System.ExecutionEngineException' was thrown."

Any idea what might be going on?知道会发生什么吗? I did check and it does not appear to be due to the creation of the plugin to run on different threads than the unloading of the context.我确实检查过,这似乎不是因为创建插件以在与卸载上下文不同的线程上运行。

Here is my code:这是我的代码:

public static class PluginManager
{
     private static readonly ILogger _logger;
     private static readonly Dictionary<string, WeakReference> _weakReferences;
     private static List<PluginConfiguration> _pluginConfigurations;

static PluginManager()
{
    _logger = LogManager.GetCurrentClassLogger();
    _weakReferences = new Dictionary<string, WeakReference>();
}

public static void Configure(List<PluginConfiguration> pluginConfigurations)
{
    _pluginConfigurations = pluginConfigurations;
}

public static List<string> GetPluginNames()
{
    return _pluginConfigurations.Select(x => x.Name).ToList();
}

public static PluginConfiguration GetPluginConfiguration(string pluginName)
{
    return _pluginConfigurations.FirstOrDefault(x => x.Name == pluginName);
}

public static List<PluginConfiguration> GetPluginConfigurations()
{
    return _pluginConfigurations;
}


[MethodImpl(MethodImplOptions.NoInlining)]
public static T GetPlugin<T>(string pluginName)
{
    var assemblyPath = $"{SharedDataModule.CoreConfiguration.PluginRootDirectory}/{pluginName}/bin/Debug/net6.0-windows/{pluginName}.dll";
    var alc = new PluginAssemblyLoadContext(assemblyPath);
    Assembly assembly = alc.LoadFromAssemblyPath(assemblyPath);
    var type = assembly.GetTypes().First(t => t.Name == pluginName);

    //store weak reference
    _weakReferences[pluginName] = new WeakReference(alc, trackResurrection: true);

    //instantiate plugin
    var plugin = Activator.CreateInstance(type, _pluginConfigurations.FirstOrDefault(x => x.Name == pluginName));

    _logger.Info($"Successfully subscribed to {pluginName} plugin");
    
    return (T)plugin;
}

public static void Unload(string pluginName)
{
    if (_weakReferences.ContainsKey(pluginName) == false)
        return;

    //obtain weak reference
    var weakRef = _weakReferences[pluginName];

    //try to remove weak reference
    _weakReferences.Remove(pluginName);

    //unload
    ((PluginAssemblyLoadContext) weakRef.Target).Unload();
    
    var task = Task.Run(() =>
    {
        for (var i = 1; weakRef.IsAlive == true && i <= 10; i++)
        {
            GC.Collect();
            GC.WaitForPendingFinalizers();
            Task.Delay(200).Wait();
        }

        if (weakRef.IsAlive == false)
            _logger.Info($"Plugin {pluginName} was successfully unloaded");
        else
            _logger.Error($"Plugin {pluginName} could not be unloaded");
    });
}

private class PluginAssemblyLoadContext : AssemblyLoadContext
{
    private readonly string _assemblyToLoadPath;
    private readonly AssemblyDependencyResolver _resolver;

    public PluginAssemblyLoadContext(string mainAssemblyToLoadPath) : base(isCollectible: true)
    {
        _assemblyToLoadPath = mainAssemblyToLoadPath;
        _resolver = new AssemblyDependencyResolver(mainAssemblyToLoadPath);
    }

    protected override Assembly Load(AssemblyName name)
    {
        string assemblyPath = _resolver.ResolveAssemblyToPath(name);
        if (assemblyPath != null)
        {
            return LoadFromAssemblyPath(assemblyPath);
        }

        return null;
    }
}

} }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 读取 Azure 密钥保管库会引发异常:System.ExecutionEngineException:“引发了‘System.ExecutionEngineException’类型的异常。” - Reading Azure key vault throws exception: System.ExecutionEngineException: 'Exception of type 'System.ExecutionEngineException' was thrown.' 为什么此代码抛出System.ExecutionEngineException - Why this code throws System.ExecutionEngineException 如何找到 System.ExecutionEngineException 异常的来源 - How to find source of System.ExecutionEngineException Exception XXX.exe中发生了未处理的“System.ExecutionEngineException”类型异常 - An unhandled exception of type 'System.ExecutionEngineException' occurred in XXX.exe DirectWriteForwarder.dll 中发生异常“System.ExecutionEngineException” - Exception 'System.ExecutionEngineException' occurred in DirectWriteForwarder.dll 给定System.ExecutionEngineException的GetMessage() - GetMessage() given an System.ExecutionEngineException 抛出System.ExecutionEngineException - System.ExecutionEngineException being thrown DBContext 构造函数中的 System.ExecutionEngineException - System.ExecutionEngineException in DBContext Constructor Windows服务的System.ExecutionEngineException - System.ExecutionEngineException With Windows Service Windows 10设备上的System.ExecutionEngineException - System.ExecutionEngineException on Windows 10 device
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM