如果跨应用程序域访问类中的静态数据会怎样?
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();
【讨论】:
以上是关于如果跨应用程序域访问类中的静态数据会怎样?的主要内容,如果未能解决你的问题,请参考以下文章