Bbrowser and reaching 10000 GUI-Handles

This forum is the place to discuss issues related to ReportPro, Xs2Ado, Vo2Ado, bBrowser and other 3rd party products
Post Reply
User avatar
ArneOrtlinghaus
Posts: 386
Joined: Tue Nov 10, 2015 7:48 am
Location: Italy

Bbrowser and reaching 10000 GUI-Handles

Post by ArneOrtlinghaus »

When having a big monitor and a table representation with many column field colors, the BBrowser creates many objects that need GUI-Handles. These are mainly brushes. When the Garbage Collector cannot destroy these objects quickly, the maximum number of GUI-Handles per Windows process (normally 10000) can be reached and give "Create ressource and other GUI Errors).

In VO we regularly verified the number of GUI Handles and called the Garbage Collector explicitly when reaching 80% of the maximum. In X# we tried to do without. The GC in Dotnet is much quicker than the VO GC, but it seems that also here we can reach the limits.

What do you think is the best method:
- Try to change all occurrences in the BBrowser and try to destroy the objects explicitly where assigned temporarily?
- Try to re-use brush-objects in the BBrowser instead of creating new ones?
- Make a similar control as we made in VO?
- Something else?

Thanks
Arne
User avatar
robert
Posts: 4290
Joined: Fri Aug 21, 2015 10:57 am
Location: Netherlands

Bbrowser and reaching 10000 GUI-Handles

Post by robert »

Arne,
Are these all "unique" brushes, or many copies of the same brush?
Would it be an idea to cache the brushes that are retrieved with CreateSolidBrush() ?
How many colors are you really using in your bBrowsers? I doubt that there are more than 10.

Robert
XSharp Development Team
The Netherlands
robert@xsharp.eu
User avatar
ArneOrtlinghaus
Posts: 386
Joined: Tue Nov 10, 2015 7:48 am
Location: Italy

Bbrowser and reaching 10000 GUI-Handles

Post by ArneOrtlinghaus »

Robert,
it is as you say: Many objects with few different colors and normally hatchstyle = SOLID.
I did never think what CreateSolidBrush does. Do you mean that instead of creating a new brushobject I use Createsolidbrush to get a handle to a brush? In this case I should pay attention that the destroy method does not destroy/delete the brush.
User avatar
Chris
Posts: 4599
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

Bbrowser and reaching 10000 GUI-Handles

Post by Chris »

Hi Arne,

How many different colors is many? I can't imagine in any case you have more than 100 different ones? In which case reusing instead of recreating sounds logical.
Chris Pyrgas

XSharp Development Team test
chris(at)xsharp.eu
User avatar
ArneOrtlinghaus
Posts: 386
Joined: Tue Nov 10, 2015 7:48 am
Location: Italy

Bbrowser and reaching 10000 GUI-Handles

Post by ArneOrtlinghaus »

When looking at the code more exactly, I discovered only one place where a brush is generated directly. In the other cases always system brushes are used. I will change the occurrence and then I will look more carefully, which GUI objects are generated in such a big quantity.
User avatar
ArneOrtlinghaus
Posts: 386
Joined: Tue Nov 10, 2015 7:48 am
Location: Italy

Bbrowser and reaching 10000 GUI-Handles

Post by ArneOrtlinghaus »

I have found some other places where a simple brush is created instead of reusing brushes - code that I have written many years ago. Finally I understand the consequences :woohoo: :-) I will change all these places and measure the GUI Handle generation.

By the way: I use always the Process Explorer to verify or exclude strange effects: Dlls loaded, virtual memory, GUI Handles, Reads/Writes, Thread stack. It is such an important tool for me.

Another important tool is the resource monitor of Windows that can be reached via the Task Manager under "Performance". Looking the disk activity sometimes shows better what happens than looking at CPU consumation.
User avatar
ArneOrtlinghaus
Posts: 386
Joined: Tue Nov 10, 2015 7:48 am
Location: Italy

Bbrowser and reaching 10000 GUI-Handles

Post by ArneOrtlinghaus »

It should be resolved now. I have made a function that buffers brushes in dependence of the color. Then I have substituted all occurences of creations of Brush{}-Objects and CreateSolidBrush-Calls, that did not use predefined Brushobjects from Windows.

So the generation of brushes in general is not the problem. But if the brush object is not destroyed in code in a tabular display the generation of objects can be so high that the Garbage Collector does not destroy them in time, because the GC does not see the need to go on more quickly - or has bigger objects to destroy.
We had similar effects with SQL Cursors that were not destroyed by program. In test situations everything went fine and then in the production environment "Maximum open cursors exceeded" messages happened because of more calls in short time.


function GetsolidBrushfromrgb(nrgb as dword) as brush
local npos as dword
local oColor as color
local obrush as object
if sabrushes == null_array
sabrushes := {}
endif
npos := ascandword (sabrushes, nrgb, 1)
if npos == 0
if alen(sabrushes) > 500
AAus (sabrushes, 1)
endif
oColor := Color {GetRValue(nrgb),GetGValue(nrgb),GetBValue(nrgb)}
obrush := brush{ocolor}
AAdd (sabrushes, {nrgb, obrush})
else
obrush := sabrushes[npos,2]
endif
return obrush
Post Reply