问题描述
各种消息来源解释说,
当一个对象派生形式MarshalByRefObject的,对象引用 将被从一个应用程序域传递到另一个,而不是 对象本身。当一个对象被标记为[Serializable接口]时, 对象将被自动序列,从一个运 应用领域到另一个,然后反序列化,以产生 的对象中的第二应用域精确副本。请注意,然后 虽然MarshalByRefObject的传递一个参考,[Serializable接口] 导致要复制的对象。 【来源】
我设计我使用的AppDomain第一个应用程序,我想知道当你把引用 MarshalByRefObjects
里面的序列化对象没有实现MarshalByRefObject的会发生什么,因为这样到目前为止,我无法找到任何关于这个问题的文件。
I'm designing my first app that uses AppDomains and I'm wondering what happens when you place references to MarshalByRefObjects
inside serializable objects that do not implement MarshalByRefObject, because so far I can't find any documentation on the subject.
例如,如果我试图返回名单,其中发生AppDomain的边界?难道我得到的
列表℃的副本; MBR>
,其中每个 MBR
是 TransparentProxy
原来的对象?而有关于混合这两种机制的技术细节的任何文档?
For example, what happens if I try to return a List<MBR>
where MBR : MarshalByRefObject
across an AppDomain boundary? Do I get a copy of the List<MBR>
where each MBR
is a TransparentProxy
to the original object? And is there any documentation about the technical details of mixing the two mechanisms?
推荐答案
我只是做了一个快速测试与名单,其中,MBR&GT;
,似乎工作,我曾希望
I just did a quick test with List<MBR>
and it seems to work as I had hoped:
public class MBR : MarshalByRefObject
{
List<MBR> _list;
public MBR() { _list = new List<MBR> { this }; }
public IList<MBR> Test() { return _list; }
public int X { get; set; }
}
// Later...
var mbr = AppDomainStarter.Start<MBR>(@"C:\Program Files", "test", null, true);
var list = mbr.Test();
list[0].X = 42;
list.Clear();
Debug.WriteLine(string.Format("X={0}, Count={1}", mbr.X, mbr.Test().Count));
输出为 X = 42,计数= 1
,调试器显示了名单,其中,MBR&GT;
包含 __ TransparentProxy
。所以很明显,在 MarshalByRefObject的
被成功地被编组通过值另一个对象中引用封。
The output is X=42, Count=1
, and the debugger shows that the List<MBR>
contains a __TransparentProxy
. So clearly, the MarshalByRefObject
is successfully marshaled by reference inside another object that was marshaled by value.
我还是想看到的文档或技术细节,如果任何人都可以找到一些。
I would still like to see documentation or technical details if anyone can find some.
对于任何人谁是好奇,我写了这个方便,花花公子沙箱AppDomainStarter:
For anyone who is curious, I wrote this handy-dandy sandbox AppDomainStarter:
/// <summary><see cref="AppDomainStarter.Start"/> starts an AppDomain.</summary>
public static class AppDomainStarter
{
/// <summary>Creates a type in a new sandbox-friendly AppDomain.</summary>
/// <typeparam name="T">A trusted type derived MarshalByRefObject to create
/// in the new AppDomain. The constructor of this type must catch any
/// untrusted exceptions so that no untrusted exception can escape the new
/// AppDomain.</typeparam>
/// <param name="baseFolder">Value to use for AppDomainSetup.ApplicationBase.
/// The AppDomain will be able to use any assemblies in this folder.</param>
/// <param name="appDomainName">A friendly name for the AppDomain. MSDN
/// does not state whether or not the name must be unique.</param>
/// <param name="constructorArgs">Arguments to send to the constructor of T,
/// or null to call the default constructor. Do not send arguments of
/// untrusted types this way.</param>
/// <param name="partialTrust">Whether the new AppDomain should run in
/// partial-trust mode.</param>
/// <returns>A remote proxy to an instance of type T. You can call methods
/// of T and the calls will be marshalled across the AppDomain boundary.</returns>
public static T Start<T>(string baseFolder, string appDomainName,
object[] constructorArgs, bool partialTrust)
where T : MarshalByRefObject
{
// With help from http://msdn.microsoft.com/en-us/magazine/cc163701.aspx
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = baseFolder;
AppDomain newDomain;
if (partialTrust) {
var permSet = new PermissionSet(PermissionState.None);
permSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
permSet.AddPermission(new UIPermission(PermissionState.Unrestricted));
newDomain = AppDomain.CreateDomain(appDomainName, null, setup, permSet);
} else {
newDomain = AppDomain.CreateDomain(appDomainName, null, setup);
}
return (T)Activator.CreateInstanceFrom(newDomain,
typeof(T).Assembly.ManifestModule.FullyQualifiedName,
typeof(T).FullName, false,
0, null, constructorArgs, null, null).Unwrap();
}
}
这篇关于混合MarshalByRefObject的和序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!