gpt4 book ai didi

c# - AssemblyLoadContext 是否隔离静态变量?

转载 作者:行者123 更新时间:2023-12-03 21:25:52 28 4
gpt4 key购买 nike

Announcement告诉我们:

Assembly unloadability is a new capability of AssemblyLoadContext. This new feature is largely transparent from an API perspective, exposed with just a few new APIs. It enables a loader context to be unloaded, releasing all memory for instantiated types, static fields and for the assembly itself. An application should be able to load and unload assemblies via this mechanism forever without experiencing a memory leak.



还有,这个 design notes提到了“静态”。

我试过这个简单的测试:
static void Main()
{
Proxy.X = 15;
var alc = new AssemblyLoadContext("MyTest", true);
var asm = alc.LoadFromAssemblyName(typeof(Program).Assembly.GetName());
var proxy = (Proxy)asm.CreateInstance(typeof(Proxy).FullName);
Console.WriteLine(proxy.Increment());
}

class Proxy
{
public static int X;
public int Increment() => ++X;
}

它输出“16”,这意味着隔离不起作用。

我的目标是对可以抛出异常的类静态成员进行单元测试。通常的测试可以通过触发类型初始值设定项来影响彼此的行为,因此我需要以尽可能便宜的方式隔离它们。测试应在 .NET Core 3.0 上运行。

这样做对吗,可以 AssemblyLoadContext帮助它?

最佳答案

是的,它确实隔离了静态变量。

如果我们看 newest design notes ,我们看到这个补充:

LoadFromAssemblyName

This method can be used to load an assembly into a load context different from the load context of the currently executing assembly. The assembly will be loaded into the load context on which the method is called. If the context can't resolve the assembly in its Load method the assembly loading will defer to the Default load context. In such case it's possible the loaded assembly is from the Default context even though the method was called on a non-default context.

Calling this method directly on the AssemblyLoadContext.Default will only load the assembly from the Default context. Depending on the caller the Default may or may not be different from the load context of the currently executing assembly.

This method does not "forcefully" load the assembly into the specified context. It basically initiates a bind to the specified assembly name on the specified context. That bind operation will go through the full binding resolution logic which is free to resolve the assembly from any context (in reality the most likely outcome is either the specified context or the default context). This process is described above.

To make sure a specified assembly is loaded into the specified load context call AssemblyLoadContext.LoadFromAssemblyPath and specify the path to the assembly file.



这有点令人沮丧,因为现在我需要确定要加载的程序集的确切位置(没有简单的方法可以“克隆”已加载的程序集)。

此代码有效(输出“1”):
static void Main()
{
Proxy.X = 15;
var alc = new AssemblyLoadContext("MyTest", true);
var asm = alc.LoadFromAssemblyPath(typeof(Program).Assembly.Location);
var proxy = asm.CreateInstance(typeof(Proxy).FullName);
Console.WriteLine(proxy.GetType().GetMethod("Increment").Invoke(null, null));
}

class Proxy
{
public static int X;
public static int Increment() => ++X;
}

(注意,现在我们不能强制转换为 Proxy 类,因为它与 proxy 变量的运行时类不同,即使是同一个类...)

关于c# - AssemblyLoadContext 是否隔离静态变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59019761/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com