如何加快Cross-AppDomain调用?

时间:2014-12-12 20:04:06

标签: c# .net performance cross-domain appdomain

我们开发了一些与DB队列配合使用的系统,以及哪些组件位于单独的Windows服务中。我们有一个想法,即在单个可执行文件中执行所有组件,但是在单独的AppDomain中。主要目的是防止整个系统在单个组件崩溃时崩溃。

在执行少量测试后,我们遇到了Cross-AppDomain调用太慢的问题。我尝试使用强名称对程序集进行签名并将它们放到GAC并应用LoaderOptimization.MultiDomain(Host),但性能仍然不可接受:简单的单个AppDomain调用和每秒90 000个调用的14 000 000个呼叫/秒在跨域呼叫模式下。在应用程序中,执行两个调用:第一个从默认AppDomain到非默认AppDomain,第二个调用 - 在相反方向。 90 000个调用/秒是非常好的结果,但考虑到测试应用程序的简单性,并且在将系统的复杂性投射到多个AppDomain方法后,我们发现它太慢了。

主要问题是:有没有办法显着加快跨域调用?也许可以消除某种检查?

代码:

class Program
{
    public class TestMessage : MarshalByRefObject { }

    public class TestClass : MarshalByRefObject
    {
        private TestClass() { }


        public void TestMethod(TestMessage message) { }


        public static TestClass Create(bool defaultDomain)
        {
            if (defaultDomain)
            {
                return TestClass.createDefaultDomain();
            }

            return TestClass.createInNewDomain();
        }


        private static TestClass createDefaultDomain()
        {
            return new TestClass();
        }

        private static TestClass createInNewDomain()
        {
            AppDomain appDomain = AppDomain.CreateDomain("NewDomain");

            return appDomain.CreateInstance(
                typeof(TestClass).Assembly.FullName,
                typeof(TestClass).FullName,
                true, BindingFlags.NonPublic | BindingFlags.Instance,
                null, null, null, null)
                .Unwrap() as TestClass;
        }
    }

    [STAThread]
    [LoaderOptimization(LoaderOptimization.MultiDomain)]
    static void Main(string[] args)
    {
        TestClass testClass = TestClass.Create(true);
        TestMessage message = new TestMessage();

        int calls = 0;

        Stopwatch sw = Stopwatch.StartNew();

        while (sw.ElapsedMilliseconds < 10000)
        {
            testClass.TestMethod(message);

            calls++;
        }

        sw.Start();

        Console.WriteLine("{0:N3}", calls / sw.Elapsed.TotalSeconds);
    }
}

1 个答案:

答案 0 :(得分:0)

带有多个AppDomain的link你运气不好:

  

直接调用只是一些操作码,但通过远程处理,涉及多个类,真实/透明代理,安全检查,序列化

如果您唯一担心的是组件崩溃没有传播(而不是例如阻止与动态加载到单个AppDomain相关联的seems,或阻止直接访问),您可以通过以下方式解决问题:尝试/捕获这些组件中的所有代码调用。如果你正在考虑/使用多个AppDomain,那么无论如何都不会有那么多不同的交互点,所以尝试/捕捉它,加上或许尝试/捕获你(自己创建的)线程的最外层 - 这是一个总的来说好主意 - 可能足够好。

如果您需要阻止随机第三方代码访问其他代码/数据,则单个域名是不可能的。