是什么原因导致的Windows在这WPF功能区应用程序挂起 [英] What causes Windows to hang in this WPF Ribbon application

查看:255
本文介绍了是什么原因导致的Windows在这WPF功能区应用程序挂起的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们已经有几个问题,一个相当大的和复杂的桌面应用程序,其中使用微软的色带为WPF(或连接到该事物的组合)导致计算机挂起。

该归结code以下,似乎触发了一些计算机在Windows死机的情况。某些计算机会遇到此挂起每一次,有些人会永远不会遇到它。该行会,一些计算机上使整个会话锁定(包括NUM LOCK和大写锁定),但在其他情况下,鼠标也将移动(NUM LOCK还是关门大吉)。当计算机没有响应,这似乎像远程登录和网络共享仍然有效,但它不可能结束控制台会话。

总之,似乎是行为的根本原因是几件事情的组合:

  • 微软丝带WPF
  • 在Windows窗体应用程序托管的WPF控件在ElementHost的
  • 使用双缓冲的Windows窗体(通过使用的CreateParams的)
  • 的软件渲染的WPF色带使用

我们已经在以后使用解决了这个问题, WS_EX_COMPOSITED 仅在几个选定的形式,但我非常想揭开这个问题的根本原因。

我还没有发现重现亨有直接的方式,但这种很小的应用程序似乎得到企业完成的,至少在某些机器上,做了一点的最大化/还原和悬停鼠标功能区上方按钮。

下面code编译为x86的.NET 4.0,对微软WPF丝带的.NET 4.0库。

使用系统; 使用System.Windows.Forms的; 使用Microsoft.Windows.Controls.Ribbon; 使用System.Windows.Interop; 使用System.Windows.Forms.Integration; 命名空间WindowsRibbonHang {     公共类Form1中:形态     {         保护覆盖的CreateParams的CreateParams         {             得到             {                 的CreateParams CP = base.CreateParams;                 cp.ExStyle | = 0x02000000; //开启WS_EX_COMPOSITED                 返回CP;             }         }         公共Form1中()         {             丝带丝带=新的Ribbon();             RibbonTab选项卡=新RibbonTab {标题=FooTab};             ribbon.Items.Add(标签);             RibbonSplitButton按钮=新RibbonSplitButton {标签=FooButton};             tab.Items.Add(按钮);             ElementHost的ElementHost的=新的ElementHost             {                 码头= DockStyle.Fill,                 儿童=织​​带,             };             Controls.Add被(ElementHost的);             码头= DockStyle.Fill;             ribbon.Loaded + =(发件人,参数)=> {                 HwndSource hwndSource = System.Windows presentationSource.FromVisual(带)为HwndSource。                 HwndTarget hwndTarget = hwndSource.CompositionTarget;                 hwndTarget.RenderMode = RenderMode.SoftwareOnly;             };         }     }     静态类节目     {         ///<总结>         ///的主入口点的应用程序。         ///< /总结>         [STAThread]         静态无效的主要()         {             Application.EnableVisualStyles();             Application.SetCompatibleTextRenderingDefault(假);             Application.Run(新Form1中());         }     } }

解决方案

尝试检查受影响的计算机上的图形驱动程序是最新的。 WPF的作品非常不同,从传统的GDI code,所以有时不可靠的驱动程序可能会导致您所描述的那样的问题。

We've had a few problems with a rather large and complex desktop application where the use of Microsoft Ribbon for WPF (or a combination of things connected to this) causes the computer to hang.

The boiled down code below seems to trigger a Windows hang situation on a number of computers. Some computers will experience this hang every time, some will never experience it. The hang will, on some computer make the entire session lock up (including num lock and caps lock), but on others, the mouse will still move (num lock still out of business). When the computer becomes unresponsive, it seems things like remote logon and network sharing still works, but it is not possible to end the console session.

In short, what seems to be the root cause of the behavior is the combination of a few things:

  • Microsoft Ribbon for WPF
  • Windows Forms application hosting the WPF control in an ElementHost
  • The use of double buffered Windows Forms (by use of CreateParams)
  • The use of software rendering on the WPF ribbon

We have later solved this issue by using WS_EX_COMPOSITED only on a few selected forms, but I'd very much like to uncover the root cause of this issue.

I've yet to discover a straight forward way to reproduce the hang, but this minimal application seems to get the business done, at least on some machines, by doing a bit of maximize/restore and hovering the mouse above the ribbon button.

The following code is compiled as x86 .NET 4.0, against the Microsoft WPF Ribbon .NET 4.0 library.

using System;
using System.Windows.Forms;
using Microsoft.Windows.Controls.Ribbon;
using System.Windows.Interop;
using System.Windows.Forms.Integration;

namespace WindowsRibbonHang
{
    public class Form1 : Form
    {
        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x02000000;  // Turn on WS_EX_COMPOSITED
                return cp;
            }
        }

        public Form1()
        {
            Ribbon ribbon = new Ribbon();

            RibbonTab tab = new RibbonTab { Header = "FooTab" };
            ribbon.Items.Add(tab);

            RibbonSplitButton button = new RibbonSplitButton { Label = "FooButton" };
            tab.Items.Add(button);

            ElementHost elementHost = new ElementHost
            {
                Dock = DockStyle.Fill,
                Child = ribbon,
            };

            Controls.Add(elementHost);
            Dock = DockStyle.Fill;

            ribbon.Loaded += (sender, args) => {
                HwndSource hwndSource = System.Windows.PresentationSource.FromVisual(ribbon) as HwndSource;
                HwndTarget hwndTarget = hwndSource.CompositionTarget;
                hwndTarget.RenderMode = RenderMode.SoftwareOnly;
            };
        }
    }

    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}

解决方案

Try checking that the graphics drivers on the affected computers are up-to-date. WPF works very differently from traditional GDI code, so sometimes unreliable drivers can cause the kind of problem that you describe.

这篇关于是什么原因导致的Windows在这WPF功能区应用程序挂起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆