且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

WPF中的一个bug造成CPU资源拉满

更新时间:2022-05-18 07:43:24

在 WPF 里可以使用DashStyle属性实现虚线的功能,通过传入double数组即可实现这个功能,但是如果传入的数组是[0,0]就表示先绘制零宽度线条,再空出零宽度的间隔。这其实是一个震荡收敛,要么整条线绘制的是实线,要么就是什么也不绘制,成为空白。那么就存在一个问题,就是求一个线段有多少个无穷小的点组成的问题。计算机虽然有精度限制,但这个问题所需要计算量非常大,因此会造成渲染线程使得CPU直接拉满。例如下面这段代码:

    class Test : FrameworkElement
    {
        public Test()
        {
            Width = 1000;
            Height = 1000;
        }
        protected override void OnRender(DrawingContext drawingContext)
        {
            var pen = new Pen()
            {
                Brush = Brushes.Black,
                DashStyle = new DashStyle(new double[] { 0, 0 }, 0),
                Thickness = 10,
            };
            var geometry = new LineGeometry(new Point(0, 0), new Point(500, 0));
            drawingContext.DrawGeometry(Brushes.Beige, pen, geometry);
            base.OnRender(drawingContext);
        }
    }

将以上的Test类放到界面里面,并在XAML代码里中放入Grid:

<Grid x:Name="Grid"></Grid>

在代码中,我们设置鼠标移动的时候设置刷新Test:

public partial class MainWindow : Window
{
    private Test t{ get; }
    public MainWindow()
    {
        InitializeComponent();
        t= new Test();
        Grid.Children.Add(t);
        MouseMove += MainWindow_MouseMove;
    }
    private void MainWindow_MouseMove(object sender, MouseEventArgs e)
    {
        Test.InvalidateVisual();
    }
}

运行上述代码,并且鼠标在窗体内华东,我们在任务管理器中可以看到CPU使用率接近于100%。关于这个问题国内已经有人报告给了WPF的开发团队,但目前WPF开发团队并未回复,而且也没有发布补丁,但是就这个问题形成的原因来说,一般在项目中几乎遇不到,因为没有人会将DashStyle属性设置为[0,0],除非他脑子瓦特了。