C#:沙箱和性能(MarshalByRefObject)

| 我已经用C#编写了一个非常基本的Web服务器,该服务器加载了自定义模块,这些自定义模块可以处理对特定域名的请求,如配置文件中所指定。自定义模块已加载到新的AppDomain中,因为我需要能够动态卸载它们(也对安全性有好处)。由于模块已加载到新的AppDomain中,因此所有参数和返回类型均为MarshalByRefObject。这工作正常,我传递了一个从MarshalByRefObject继承的HttpRequest对象,并返回了一个由Web服务器发送回客户端的LinkedList。 所有这些工作都很好,但是很多数据作为byte []传递,我相信MarshalByRefObject的代理会将所有字节从新的AppDomain复制到主AppDomain,而不是直接访问它们。因此,如果我对此是正确的,如果其中一个模块将发送5MB文件作为响应,则将在模块中加载/生成5MB,然后将其从模块AppDomain复制到主AppDomain,最后通过套接字返回到客户端。 因此,我的问题是:我能以某种方式解决这个问题,以便它不会在AppDomain之间复制太多数据吗?还是有一种更好的方式而不使用MarshalByRefObject?     
已邀请:
        字符串是按进程而不是每个应用程序域(出于性能原因)。如果要传递html / xml(而不传递二进制数据),则可以将api更改为使用字符串而不是字节[]。在普通情况下,甚至可能支持字符串,在二进制情况下,甚至可以支持byte []。     
        我最终将SocketInformation传递给新的AppDomain并在那里(在新的AppDomain中)创建了一个新的套接字对象。 在我的“沙盒包装对象”中,我具有以下功能:
internal class Sandbox
{
    private AppDomain _AppDomain;
    private WebApplicationProxy _Proxy;

    public Sandbox(string assemblyFile)
    {
        _AppDomain = AppDomain.CreateDomain(Guid.NewGuid().ToString());
        _Proxy = (WebApplicationProxy)_AppDomain.CreateInstanceAndUnwrap(
                                                    Assembly.GetExecutingAssembly().FullName,
                                                    \"WebServer.WebApplication.Proxy\");
        _Proxy.Initialize(assemblyFile);
    }
    public void SendResponse(Socket client, HttpRequest request)
    {
        SocketInformation clientInfo = client.DuplicateAndClose(Process.GetCurrentProcess().Id);
        _Proxy.GetResponse(clientInfo, request);
    }
}
在新的AppDomain“恢复”套接字中,我不确定幕后到底发生了什么……这是代码:
internal class Proxy : MarshalByRefObject
{
    private AppController _AppController;

    public void Initialize(string assemblyFile)
    {
        Assembly asm = Assembly.LoadFile(assemblyFile);
        var q = from t in asm.GetTypes()
                where t.GetInterfaces().Contains(typeof(AppController))
                      && !t.IsAbstract && t.IsClass
                select t;
        foreach (Type t in q)
        {
            _AppController = (AppController)Activator.CreateInstance(t);
        }
    }

    public void SendResponse(SocketInformation clientInfo, HttpRequest req)
    {
        Socket client = new Socket(clientInfo);

        LinkedList<byte[]> toSend = _AppController.GetResponse(client, req);

        foreach (byte[] bytes in toSend)
            client.Send(bytes);

        client.Close();
    }
}
我不确定调用ѭ2或在新域中创建新的Socket对象时会发生什么情况的细节,但是到目前为止,它运行良好。     
        如果是.NET 4.0,可以选择使用“内存映射”文件吗?     

要回复问题请先登录注册