c# - 应用程序域内的静态变量
问题描述
我在 C# 库程序集中有以下类。
public static class TestClass
{
static int counter = 0;
static TestClass()
{
System.Diagnostics.Debug.Print("TestLibrary.TestClass is constructed...");
}
public static void Say()
{
System.Diagnostics.Debug.Print($"TestClass.Say called {counter++} times");
}
}
[Serializable]
public class TestLibraryProxy
{
static int _executionCount = 0;
public void Execute()
{
System.Diagnostics.Debug.Print($"TestLibraryProxy Execute [{_executionCount++}]");
TestClass.Say();
TestClass.Say();
}
}
我试图从另一个 C# 应用程序将上述程序集加载到应用程序域并调用 TestLibraryProxy.Execute() 方法。
class Program
{
static void Main(string[] args)
{
CreateAppDomainAndCallStaticMethod("MyDomain1");
CreateAppDomainAndCallStaticMethod("MyDomain2");
CreateAppDomainAndCallStaticMethod("MyDomain3");
CreateAppDomainAndCallStaticMethod("MyDomain4");
}
private static void CreateAppDomainAndCallStaticMethod(string domainName)
{
AppDomain domain = AppDomain.CreateDomain(domainName);
var k = domain.CreateInstanceAndUnwrap("TestLibrary", typeof(TestLibraryProxy).FullName) as TestLibraryProxy;
k.Execute();
AppDomain.Unload(domain);
}
}
Output
TestLibraryProxy Execute [0]
TestLibrary.TestClass is constructed...
TestClass.Say called 0 times
TestClass.Say called 1 times
TestLibraryProxy Execute [1]
TestClass.Say called 2 times
TestClass.Say called 3 times
TestLibraryProxy Execute [2]
TestClass.Say called 4 times
TestClass.Say called 5 times
TestLibraryProxy Execute [3]
TestClass.Say called 6 times
TestClass.Say called 7 times
我注意到 TestClass 中的静态计数器值在应用程序域中得到保留。即使我多次加载和卸载应用程序域,此值也会保留。
我读过静态变量存储在应用程序域级别。但看起来不是真的?知道 CLR 如何跨应用程序域管理静态数据。
解决方案
这是因为TestLibraryProxy
已经被标记了[Serializable]
。
相反,它应该继承自MarshalByRefObject
.
基本上你所做的是在另一个中创建一个对象,AppDomain
然后将其复制(序列化)到原始AppDomain
. 使用MarshalByRefObject
可以避免这种情况。它确保对象不被复制 - 相反,您将处理对原始对象的引用(在不同的 中运行AppDomain
)。
如果你做出改变
public class TestLibraryProxy : MarshalByRefObject
输出变为:
TestLibraryProxy Execute [0]
TestLibrary.TestClass is constructed...
TestClass.Say called 0 times
TestClass.Say called 1 times
重复多次
推荐阅读
- jquery - 使用 jQuery 使用 ID 填充模式
- sql - 如何将不同的列值转置为列名并将其他列值映射到每个列名
- java - ArrayDeque 在删除/添加时是否有移动元素的开销?
- html - 将类添加到菜单问题
- android - 如何在android中正常记录和验证截图测试
- java - 从没有输入字段的 JSP 创建 POST 请求以执行几个不同的操作
- javascript - 无法修复十进制数的正则表达式
- python - 如果 stdout.channel.recv() 上的条件不起作用,则 SSH paramiko
- jquery - 如何使用 Laravel 检索 JSON 数据并将其存储到数据库中
- java - Apache Ignite SQL 性能 COUNT 与 SELECT