WPF暖AppDomain启动性能(Application.RunInternal、XamlReader.LoadBaml)

WPF暖AppDomain启动性能(Application.RunInternal、XamlReader.LoadBaml),wpf,performance,appdomain,Wpf,Performance,Appdomain,我有相对简单的应用程序,但温暖(秒等)启动时间是可怕的3-5秒。Profiler(VS2010,CPU采样)显示80%以上的时间花在Application.RunInternal(~40%)和XamlRader.LoadBaml(~40%)函数上 问题的根源在于窗口是在非默认AppDomain中创建的。如果我将窗口创建移动到默认的AppDomain或授予AppDomain不受限制的权限集,则一切都会像预期的那样快 我正在测试: Windows7x64 .NET4.0 4Gb内存 GeForc

我有相对简单的应用程序,但温暖(秒等)启动时间是可怕的3-5秒。Profiler(VS2010,CPU采样)显示80%以上的时间花在Application.RunInternal(~40%)和XamlRader.LoadBaml(~40%)函数上

问题的根源在于窗口是在非默认AppDomain中创建的。如果我将窗口创建移动到默认的AppDomain或授予AppDomain不受限制的权限集,则一切都会像预期的那样快


我正在测试:

  • Windows7x64
  • .NET4.0
  • 4Gb内存
  • GeForce 9800GT 1Gb

我用这种方式创建AppDomain

var permissionSet = new PermissionSet(null);

permissionSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution | SecurityPermissionFlag.SerializationFormatter | SecurityPermissionFlag.UnmanagedCode));
permissionSet.AddPermission(new ReflectionPermission(PermissionState.Unrestricted));
permissionSet.AddPermission(new UIPermission(PermissionState.Unrestricted));
permissionSet.AddPermission(new MediaPermission(PermissionState.Unrestricted));
permissionSet.AddPermission(new FileDialogPermission(PermissionState.Unrestricted));

var appDomainSetup =
    new AppDomainSetup
    {
        ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase,
        ApplicationName = AppDomain.CurrentDomain.SetupInformation.ApplicationName,
        DisallowApplicationBaseProbing = false,
        DisallowBindingRedirects = true,
        DisallowCodeDownload = true,
        DisallowPublisherPolicy = true,
        LoaderOptimization = LoaderOptimization.MultiDomainHost
    };

_appDomain =
    AppDomain.CreateDomain(
        name,
        null,
        appDomainSetup,
        permissionSet,
        new[]
    {
        // a few types I need
        typeof(...).Assembly.Evidence.GetHostEvidence<StrongName>(),
    });
var permissionSet=新的permissionSet(null);
permissionSet.AddPermission(新的SecurityPermission(SecurityPermissionFlag.Execution | SecurityPermissionFlag.SerializationFormatter | SecurityPermissionFlag.UnmanagedCode));
permissionSet.AddPermission(新的ReflectionPermission(PermissionState.Unrestricted));
permissionSet.AddPermission(新UIPermission(PermissionState.Unrestricted));
permissionSet.AddPermission(新的MediaPermission(PermissionState.Unrestricted));
permissionSet.AddPermission(新文件对话框权限(PermissionState.Unrestricted));
var appDomainSetup=
新AppDomainSetup
{
ApplicationBase=AppDomain.CurrentDomain.SetupInformation.ApplicationBase,
ApplicationName=AppDomain.CurrentDomain.SetupInformation.ApplicationName,
DisallowApplicationBaseProbling=false,
DisallowBindingRedirects=true,
DisallowCodeDownload=true,
DisallowPublisherPolicy=true,
LoaderOptimization=LoaderOptimization.MultiDomainHost
};
_appDomain=
AppDomain.CreateDomain(
名称
无效的
appDomainSetup,
许可证集,
新[]
{
//我需要几种
typeof(…).Assembly.Evidence.GetHostEvidence(),
});

即使我将XAML剥离为空窗口,行为也保持不变

<Window
    x:Class="Rosmurta.Extensibility.WpfUI.RosmurtaWindow"
    x:ClassModifier="internal"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Test"
    Height="480"
    Width="640"
    WindowStyle="SingleBorderWindow">
    <Grid>
    </Grid>
</Window>

XamlRader.LoadBaml不需要解析太多内容,但它将超过30%的启动时间用于空窗口事件


我试过了(但没用)

  • 添加到App.config
  • 将[LoaderOptimization(LoaderOptimization.MultiDomainHost)]阿曲布他丁添加到主方法中
  • 向所有程序集添加签名


还可以做什么?

嗨,进入实际调用怎么样?@Dmitry,这些是PresentationFramework.dll中的方法。即使我以某种方式介入他们,我也无法分析他们。很难,但你不能雇佣Rob Relyea,对吗?:)即使如此-他要问的第一个问题是,为什么你需要在单独的应用程序域中加载你的应用程序?:)“3-5秒”延迟应该是有形的,足以在调试时抓住原因,在我看来,这似乎是唯一可行的选择。答案很简单,安全。正如您可以从我提供的源代码中看到的,这里应用了一些CAS限制。我不能理解的是,并没有第一次出现异常或其他问题的迹象,代码在受限域中的速度很慢。在非限制非默认域中,一切都是快速的,所以CAS是直接或间接的原因。我会继续尝试调试这个,只是觉得有人可能有答案。那么,你是说你不能通过在单独的appdomain中加载你的应用程序来重新处理这个问题?是否存在严重影响性能的特定CAS设置知道了这一点,你就可以进入.net代码,看看那里发生了什么。很抱歉给出了这么宽泛的答案,但这是我能看到的唯一方法。嗨,进入实际调用怎么样?@Dmitry,这些是PresentationFramework.dll中的方法。即使我以某种方式介入他们,我也无法分析他们。很难,但你不能雇佣Rob Relyea,对吗?:)即使如此-他要问的第一个问题是,为什么你需要在单独的应用程序域中加载你的应用程序?:)“3-5秒”延迟应该是有形的,足以在调试时抓住原因,在我看来,这似乎是唯一可行的选择。答案很简单,安全。正如您可以从我提供的源代码中看到的,这里应用了一些CAS限制。我不能理解的是,并没有第一次出现异常或其他问题的迹象,代码在受限域中的速度很慢。在非限制非默认域中,一切都是快速的,所以CAS是直接或间接的原因。我会继续尝试调试这个,只是觉得有人可能有答案。那么,你是说你不能通过在单独的appdomain中加载你的应用程序来重新处理这个问题?是否存在严重影响性能的特定CAS设置知道了这一点,你就可以进入.net代码,看看那里发生了什么。对不起,我的回答太笼统了,但这是我唯一能看到的。