如果跨应用程序域访问类中的静态数据会怎样?

Posted

技术标签:

【中文标题】如果跨应用程序域访问类中的静态数据会怎样?【英文标题】:What happens to the static data in a class if it is accessed across app domains? 【发布时间】:2011-10-31 18:15:48 【问题描述】:

我有一个包含一些静态数据的静态类。如果从不同的应用程序域访问数据会怎样?

    每个域都会有一个静态类的副本吗?

    原始类型会被复制吗?

    如果数据是可序列化的呢?

【问题讨论】:

【参考方案1】:

AppDomain 之间的内存不共享。默认情况下,对象是深度克隆,如果它们是 MarshalByRef,那么它类似于跨 AppDomain 执行调用的远程处理,因此看起来它的共享状态。

MarshalByRefObject 是对象的基类,这些对象通过使用代理交换消息来跨应用程序域边界进行通信。不从MarshalByRefObject 继承的对象按值隐式封送。当远程应用程序按值引用编组对象时,该对象的副本将跨应用程序域边界传递。

我不相信您实际上可以使用 AppDomain 方法调用静态成员,最好的办法是将静态调用包装在实例类中并使用 DoCallback 在另一个域中执行该代码并收集状态在MarshalByRef 对象中。

查看MSDN上的示例

【讨论】:

【参考方案2】:

这个帖子比较完整: MSDN Blogs > cbrumme's WebLog > AppDomains ("application domains")

它说:

无论类型是否与域无关,每个 AppDomain 都必须获取它的 自己的静态字段副本。并且必须在每个类中运行一个类构造函数 这些 AppDomain 中,以确保这些静态字段正确 初始化。

我同意。

【讨论】:

【参考方案3】:

一般情况下,您将拥有一份数据副本,并为每个 appdomain 单独初始化。

    是的,每个应用程序域都会有一个静态类的副本 没有。 没关系。

如果这是一个具体问题,您可能想分享一个您正在做的事情的例子。存在将复制数据的编组方案。

【讨论】:

【参考方案4】:

您必须在每个应用程序域中故意加载静态类才能访问它,对于每个应用程序域,它将维护自己的静态数据。

检查this: Static Fields in AppDomain

【讨论】:

【参考方案5】:

打印 0,1,2 和 0,1,2 的简单程序表明 appdomain 不共享静态数据。

刚刚修改了一个:Static Fields in AppDomain

public static class Class1

    private static int Value = 0;
    public static void IncrementAndPrint()
    
        Console.WriteLine(Value++);
    


public class Foo : MarshalByRefObject

    public void Bar()
    
        Class1.IncrementAndPrint();
    


class Program

    static void Main(string[] args)
    
        var appDomain1 = System.AppDomain.CreateDomain("AppDomain1");
        var appDomain2 = System.AppDomain.CreateDomain("AppDomain2");    

        var class1InAppDomain1 = (Foo)appDomain1.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, "ConsoleApplication1.Foo");
        var class1InAppDomain2 = (Foo)appDomain2.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, "ConsoleApplication1.Foo");
        class1InAppDomain1.Bar();
        class1InAppDomain1.Bar();
        class1InAppDomain1.Bar();

        class1InAppDomain2.Bar();
        class1InAppDomain2.Bar();
        class1InAppDomain2.Bar();
    

【讨论】:

以上是关于如果跨应用程序域访问类中的静态数据会怎样?的主要内容,如果未能解决你的问题,请参考以下文章

28静态对象(static)

解决.Net Core跨域问题

前端跨域访问

使用闭包跨域开发

前后端分离项目,如何解决跨域问题

建议17:使用闭包跨域开发