用perfmon简单分析GDI+性能和代码的一点小改进

Paint事件被触发了多少次?比较简单的方式,我们自己做一个perfmon能用的counter。看代码:

 1          private   void  button1_Click( object  sender, EventArgs e)
 2          {
 3            
 4            if (!PerformanceCounterCategory.Exists("GDI+ Monitor"))
 5            {
 6                CounterCreationDataCollection ccdc = new CounterCreationDataCollection();
 7
 8                CounterCreationData totalPaint = new CounterCreationData();
 9                totalPaint.CounterName = "# operator executed";
10                totalPaint.CounterHelp = "Counts of OnPaint events called";
11                totalPaint.CounterType = PerformanceCounterType.NumberOfItems32;
12
13                ccdc.Add(totalPaint);
14
15                PerformanceCounterCategory.Create("GDI+ Monitor""Some counters for GDI+ objects", PerformanceCounterCategoryType.MultiInstance, ccdc);
16            }

17        }

好,点一下button1之后,我们就可以在perfmon中看到GDI+ Monitor这个category了,然后只有一个counter,就是# operator executed

然后在winform中增加这么一段:
           paintcall  =   new  PerformanceCounter();
            paintcall.CategoryName 
=   " GDI+ Monitor " ;
            paintcall.CounterName 
=   " # operator executed " ;
            paintcall.MachineName 
=   " . " ;
            paintcall.ReadOnly 
=   false ;

好了,代码里面可以用paintcall这个变量了。我们现在的需求是监视Paint被触发了多少次,那么可以在代码中这么写:
 1             Graphics g2  =  e.Graphics;
 2
 3             Bitmap bmp  =   new  Bitmap( this .Width,  this .Height);
 4             Graphics g  =  Graphics.FromImage(bmp);
 5
 6             paintcall.Increment();
 7
 8             Rectangle r  =   new  Rectangle( 0 0 this .Width,  this .Height);
 9             g.FillRectangle( new  LinearGradientBrush(r, Color.Red, Color.Blue, LinearGradientMode.BackwardDiagonal), r);
10
11             g2.DrawImage(bmp,  new  Point( 0 0 ));
12
13             g.Dispose();
14             g  =   null ;
15
16             bmp.Dispose();
17             bmp  =   null ;

看上面第6行,这句会把paint call增加一。当然,其他方法有很多,这里不写了。
好,跑一下perfmon,然后把我们新增加的counter add上,嗯,可以看到当窗口无效的时候,计数器就增加了。

有一个小的细节,当窗口稍微改动大小的时候,你会发现Paint被调用了多次,这个实在很郁闷。so,稍微做点手脚:
 1          private   bool  resize  =   false ;
 2          private   void  Form1_ResizeEnd( object  sender, EventArgs e)
 3          {
 4            resize = false;
 5            this.Invalidate();
 6        }

 7
 8          private   void  Form1_ResizeBegin( object  sender, EventArgs e)
 9          {
10            resize = true;
11        }

然后我们修改一下Paint事件的代码如下:
 1          private   void  Form1_Paint( object  sender, PaintEventArgs e)
 2          {
 3            if (true == resize) return;
 4
 5            Graphics g2 = e.Graphics;
 6
 7            Bitmap bmp = new Bitmap(this.Width, this.Height);
 8            Graphics g = Graphics.FromImage(bmp);
 9
10            paintcall.Increment();
11
12            Rectangle r = new Rectangle(00this.Width, this.Height);
13            g.FillRectangle(new LinearGradientBrush(r, Color.Red, Color.Blue, LinearGradientMode.BackwardDiagonal), r);
14
15            g2.DrawImage(bmp, new Point(00));
16
17            g.Dispose();
18            g = null;
19
20            bmp.Dispose();
21            bmp = null;
22        }

注意第三行,我们判断,如果在resize过程中,那么就直接返回。这样,虽然界面像白板一样,但是却少了很多Paint操作,从性能上会好不少。

转载于:https://www.cnblogs.com/juqiang/archive/2007/11/13/958168.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值