我有一个静态类,它有一些静态数据。如果数据从不同的应用域访问,会发生什么?
每个域都会有一个静态类的副本吗?
是否会复制基元类型?
如果数据可序列化怎么办?
答案 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都会有一份数据副本和单独的初始化。
如果这是一个特定问题,您可能想要分享您正在做的事情的示例。存在将复制数据的编组方案。
答案 3 :(得分:2)
您必须在每个应用程序域中故意加载静态类才能访问它,对于每个应用程序域,它将维护自己的静态数据。
答案 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();
}
}