AssemblyLoadContext长寿命

这就是我想要做的。我想拥有一个日志活动AssemblyLoadContext实例,以便快速执行已加载的程序集。 当程序集更新事件到来时,我想卸载上下文(我使用的是.net core 3),并使用程序集版本创建新的上下文。但是,当我尝试这样做时,第二次卸载时出现错误

AssemblyLoadContext长寿命

所以我猜我在做某事(非常)错误。我猜测上下文实际上并没有卸载?

如果加载的程序集依赖于某些外部dll,我还会收到一个错误消息,即使该dll位于同一文件夹中,也无法加载。我该如何预防?

任何建议将不胜感激。这是我的代码

class Program
{
    private static AssembliesContext assembliesContext;

    const int iterations = 10;

    static void Main(string[] args)
    {
        for (int i = 0; i < iterations; i++)
        {
            assembliesContext = new AssembliesContext();

            RunViaReflection();
            var wr = new WeakReference(assembliesContext);

            assembliesContext.Unload();
            assembliesContext = null;

            int retries = 0;
            while (wr.IsAlive && retries < 5)
            {
                GC.Collect();
                GC.WaitForPendingFinalizers();
                retries++;
            }

        }

    }

    [MethodImpl(MethodImplOptions.NoInlining)]
    static void RunViaReflection()
    {
        try
        {
            string dllPath = Path.Combine(Directory.getcurrentDirectory(),"..","Execution.Sample","bin","Debug","netcoreapp2.2","win10-x64","publish","Execution.Sample.dll");

            using (var fs = new FileStream(dllPath,FileMode.Open,Fileaccess.Read))
            {
                var assembly = assembliesContext.LoadFromStream(fs);

                var executableType = assembly.GetTypes()
                    .Where(x => typeof(IExecutableCode).IsAssignableFrom(x) && !x.IsInterface && !x.IsAbstract)
                    .FirstOrDefault();

                IExecutableCode instance = (IExecutableCode)activator.CreateInstance(executableType);
            }

        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }

}

public class AssembliesContext : AssemblyLoadContext
{
    public AssembliesContext(): base(true)
    {

    }

    protected override Assembly Load(AssemblyName assemblyName)
    {
        return null;
    }
}

修改


我通过将调用结果强制转换为Task来消除错误(因为它是异步方法):

((Task)method.Invoke(instance,new object[] { })).ConfigureAwait(false).Getawaiter().GetResult();

我还像这样加载了相关程序集:

foreach (var ass in assembly.GetReferencedAssemblies())
                    {
                        string path = Path.Combine(basePath,$"{ass.Name}.dll");
                        using (var dependantAssemblyStream = new FileStream(path,Fileaccess.Read))
                        {
                            assembliesContext.LoadFromStream(dependantAssemblyStream);
                        }
                    }

我仍然想知道如何管理一个寿命长的AssemblyLoadContext,因为如果我尝试将其作为类成员卸载,即使将其设置为null并实例化一个新的类,它也不会卸载。

是否需要其他方法?

yc135 回答:AssemblyLoadContext长寿命

暂时没有好的解决方案,如果你有好的解决方案,请发邮件至:iooj@foxmail.com
本文链接:https://www.f2er.com/3167717.html

大家都在问