应用程序域内的静态变量

Posted

技术标签:

【中文标题】应用程序域内的静态变量【英文标题】:static variables inside application domain 【发布时间】:2018-06-04 05:07:25 【问题描述】:

我在 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 如何跨应用程序域管理静态数据。

【问题讨论】:

Difference between Serializable and MarshalByRefObject的可能重复 这对@Vijay 有帮助吗? 【参考方案1】:

这是因为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

重复多次

【讨论】:

以上是关于应用程序域内的静态变量的主要内容,如果未能解决你的问题,请参考以下文章

Django:静态标签内的变量

Java静态内存与动态内存分配的解析

C里面静态动态,生命周期.作用域怎么区分?怎么用

static静态变量和普通变量,静态函数和普通函数

自动变量非自动变量

C--静态本地变量static