使用Winforms .net应用程序时,我们会遇到一个问题,即图像列表有时会损坏。
“损坏”是指图像数量计数错误和/或图像可能已被系统图像替换(例如对话框图标)。
例如,下面的屏幕截图显示了imageInfoCollection
显示正确的数字,但是计数显示了错误的数字。
图像列表位于用户在整个应用程序使用过程中反复打开的表单上。图像列表由窗体上的选项卡控件使用。
仅在打开表单的每5到20次之间的任何时候才会出现此问题。
加载图像列表的代码由设计人员构建,并使用来自资源的图像:
this.imageListCallTakingScreen.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageListCallTakingScreen.ImageStream")));
this.imageListCallTakingScreen.TransparentColor = System.Drawing.Color.Transparent;
this.imageListCallTakingScreen.Images.SetKeyName(0, "spinner.png");
this.imageListCallTakingScreen.Images.SetKeyName(1, "recommendation-star.png");
this.imageListCallTakingScreen.Images.SetKeyName(2, "recommendation-star_red.png");
this.imageListCallTakingScreen.Images.SetKeyName(3, "recommendation-star - Transparent.png");
this.imageListCallTakingScreen.Images.SetKeyName(4, "Initialisation_fail16.png");
this.imageListCallTakingScreen.Images.SetKeyName(5, "information_white.png");
this.imageListCallTakingScreen.Images.SetKeyName(6, "Check-icon.png");
除了在designer.cs代码中使用imagelist之外,其他任何地方都不使用imagelist来创建它并将其连接到tab控件(我放入的错误捕获行除外):
有想法吗?我们被困在这一点上,谷歌并没有出现太多。
imageInfoCollection字段正确跟踪ImageList中具有的图像数。Count属性跟踪本机Windows imagelist控件中实际存在的图像数。
There's only one way those values could have a mismatch that I can think of. Your program is leaking GDI object handles. A fairly common problem in Winform apps. That works for quite a while until you reach the operating system quota for such handles, after you've consumed 10,000 of them then Windows stops allowing you to create more. The error checking in the .NET wrapper class is not entirely kosher so this can happen without an exception getting generated. You'll see some more strange painting artifacts when you hit that limit btw.
You can get a basic diagnostic from Task Manager, Processes tab. Use View + Select columns and tick GDI Objects and USER objects. Observe these values while you operate the program like a user would. A steadily climbing value for GDI Objects spells doom. A hint that you are forgetting to use the using statement to dispose System.Drawing objects. And the garbage collector not running often enough to keep you out of trouble. You need to fix this in your code so the counter remains stable at, say, no more than several hundred objects.
稳步攀升USER Objects的值也是一个非常常见的Winforms错误。这是非常致命的,它也会增加GDI对象的数量,而GC无法解决此问题。当您使用Controls.Remove / At()或Controls.Clear()删除代码中的控件,而忘记处置删除的控件对象时,就会发生这种情况。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句