如果在应用程序域中访问静态数据,会发生什么?

时间:2011-10-31 18:15:49

标签: .net appdomain

我有一个静态类,它有一些静态数据。如果数据从不同的应用域访问,会发生什么?

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

  2. 是否会复制基元类型?

  3. 如果数据可序列化怎么办?

5 个答案:

答案 0 :(得分:6)

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

  

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

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

请参阅MSDN

上的示例

答案 1 :(得分:4)

这篇文章非常完整:http://blogs.msdn.com/b/cbrumme/archive/2003/06/01/51466.aspx

它声明:

  

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

我同意。

答案 2 :(得分:2)

通常,每个appdomain都会有一份数据副本和单独的初始化。

  1. 是的,每个应用域都会有一个静态类的副本
  2. 没有
  3. 没关系。
  4. 如果这是一个特定问题,您可能想要分享您正在做的事情的示例。存在将复制数据的编组方案。

答案 3 :(得分:2)

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

检查thisStatic Fields in AppDomain

答案 4 :(得分:0)

打印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();
    }
}