6

さまざまな情報源が

オブジェクトがMarshalByRefObjectから派生する場合、オブジェクト参照は、オブジェクト自体ではなく、あるアプリケーションドメインから別のアプリケーションドメインに渡されます。オブジェクトが[Serializable]でマークされている場合、オブジェクトは自動的にシリアル化され、あるアプリケーションドメインから別のアプリケーションドメインに転送されてから逆シリアル化され、2番目のアプリケーションドメインにオブジェクトの正確なコピーが生成されます。MarshalByRefObjectが参照を渡す間、[Serializable]によってオブジェクトがコピーされることに注意してください。[ソース]

AppDomainsを使用する最初のアプリを設計していますが、MarshalByRefObjectを実装していないシリアル化可能なオブジェクト内に参照を配置するとどうなるのでしょうかMarshalByRefObjects。これまでのところ、このテーマに関するドキュメントが見つかりません。

たとえば、AppDomainの境界を越えてList<MBR>whereを返そうとするとどうなりますか?それぞれが 元のオブジェクトMBR : MarshalByRefObjectのどこにあるかのコピーを取得できますか?また、2つのメカニズムの混合に関する技術的な詳細についてのドキュメントはありますか?List<MBR>MBRTransparentProxy

4

2 に答える 2

8

で簡単なテストを行ったところ、List<MBR>期待どおりに機能しているようです。

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, Count=1、であり、デバッガーはにががList<MBR>含まれていることを示します__TransparentProxy。明らかに、MarshalByRefObject値によってマーシャリングされた別のオブジェクト内で、参照によって正常にマーシャリングされています。

誰かが見つけたら、ドキュメントや技術的な詳細を見たいです。

好奇心旺盛な人のために、私はこの便利でダンディなサンドボックス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();
    }
}
于 2012-01-08T00:56:20.497 に答える
0

渡される最上位のオブジェクトのみがMBRである可能性があることを理解しています。あなたのシナリオでは、リストはMBRではないため、境界を越えると、シリアル化されたコピーを受け取ります。

MSDNドキュメントのこのセクションでは、この動作について説明しています。

MarshalByRefObjectは、プロキシを使用してメッセージを交換することにより、アプリケーションドメインの境界を越えて通信するオブジェクトの基本クラスです。MarshalByRefObjectから継承しないオブジェクトは、値によって暗黙的にマーシャリングされます。リモートアプリケーションが値オブジェクトによってマーシャルを参照する場合、オブジェクトのコピーがアプリケーションドメインの境界を越えて渡されます。

したがって、渡されるクラス(リスト)はMBRではないため、その内容とともにシリアル化されます。

また、質問に直接適用することはできませんが、次の動作に注意することが非常に重要です。

...オブジェクトのメンバーは、それらが作成されたアプリケーションドメインの外部では使用できません。

于 2012-01-07T23:44:53.987 に答える