Click here to Skip to main content
15,891,316 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have a large windows forms application written in C# 2008 (In the course of events I also used C# 2013, and the same problem occured).

The application crashes quite ungracefully when the number of handles exceeds 10.000

As a short term solution I want to warn the user when the number of handles exceed 8000

I tried:
int NumberOfHandles = System.Diagnostics.Process.GetCurrentProcess().HandleCount;

But I get a number of handles (e.g 286) that is quite different from the number of handles in Task Manager (3107 in this example, although actually it's user objects that has the treshold of 10.000).

My current question: How can I measure the number of User-objects as shown in taskmanager from my application?

I use the taskmanager in Windows 7, when using Windows 8 my application crashes in the same way, but I haven't been able to let task manager show me the number of user objects.

The real solution is to decrease the number of handles my application uses, but that will be a different question. In short I create a form, and in code I paint a lot of panels on this form. Every time the information is changed, the panels are repainted, but the handles to the old panels are not disposed. If someone can give me direction based on this very short description they are more than welcome!
Posted
Comments
Richard MacCutchan 4-Mar-15 12:07pm    
You need to make a serious attempt to correct your code and dispose of unused resources properly. There is no other solution to this problem.

Since Windows 2000, there is a hard coded limit of handles - 10000. (Check HKLM\Software\Microsoft\Windows NT\CurrentVersion\Windows).
This limit exists for prevent wrongly designed/developed applications to bring down the whole OS...
So as Richard told you have to work on your application...However if you got to that point that no way around and you need more than that limit, you should read the 'Pushing the Limits of Windows' blog series from Mark Russinovich, where one of the parts is about handles: http://blogs.technet.com/b/markrussinovich/archive/2009/09/29/3283844.aspx[^]
 
Share this answer
 
Comments
RobScripta 4-Mar-15 13:06pm    
I do understand that the ultimate solution is to correct the code and dispose the objects. I have found that this is not as easy as it should be, so this will take some time. At the moment I have users who suffer daily from unexpected crashes and I'm looking for a fast solution while I'm working on a real solution.
Kornfeld Eliyahu Peter 4-Mar-15 13:11pm    
Than read the blog from Mark Russinovich...
RobScripta 4-Mar-15 13:27pm    
thanks for your efforts to help me. I don't seek to push the limits of windows, the limit of 10.000 is very generous and sensible. I'm working on disposing my programmatically created objects so I don't bump in this limit anymore. For the time being I'm looking for a way to less annoy my users with a message that they should restart my application, instead of a ungracefull crash. Please be aware that a real solution is what I'm searching for to prevent serious harm done to me by my users!
Sergey Alexandrovich Kryukov 4-Mar-15 14:59pm    
Your phrase is ambiguous. Do you think the message asking to restart the application is annoying or less annoying? I would not think this is any better then ungraceful crash, maybe only a bit better. It is even irrelevant, because this message is already annoying enough to say that the whole think is totally unacceptable. Your requirements to your work need to be stronger. You bravely write "I have a large windows forms application", but this is not even the application.
—SA
Sergey Alexandrovich Kryukov 4-Mar-15 15:05pm    
I just added some practical advice as Solution 2, please see. It can really solve the problem.
—SA
Please see my comment to Solution 1.

You are perfectly right in your attempt to work at disposing. Here is the thing: in a typical pure-.NET application producing more and more handles (or even more or less pure), most or all the problems lie in the objects with the runtime types implementing System.IDisposable. It is critical to check up each and every type you use, detect those implementing that interface and call System.IDisposable.Dispose for all objects which you are going to "forget" (loose reachability): https://msdn.microsoft.com/en-us/library/system.idisposable%28v=vs.110%29.aspx[^].

It's important to dispose such objects in all cases, no ifs no buts, even if an exception is thrown. For local objects, the way to automate it in a secured way is using using statement (not to be confused with using directive!): https://msdn.microsoft.com/en-us/library/yh598w02.aspx[^].

This is pure syntactic sugar, but is very convenient and a must for good programming style.

—SA
 
Share this answer
 
v3
Comments
Kornfeld Eliyahu Peter 4-Mar-15 15:09pm    
Good advises... +5
Sergey Alexandrovich Kryukov 4-Mar-15 15:11pm    
Thank you, Peter.
—SA
Thanks to this question (the question answered my question allready!)
XML
http://stackoverflow.com/questions/19314013/determine-number-of-gdi-handles-and-user-objects


I created this code, and it gives me exactly the count that is needed.

C#
[System.Runtime.InteropServices.DllImport("User32")]
private extern static int GetGuiResources(IntPtr hProcess, int uiFlags);

public static int UserObjects()
{
    using (var process = System.Diagnostics.Process.GetCurrentProcess())
    {
        //var gdiHandles = GetGuiResources(process.Handle, 0);
        var userHandles = GetGuiResources(process.Handle, 1);
        return Convert.ToInt32(userHandles);
    }
}


And yes, I do know I have to correct my code, but I do need this code to test whether I'm moving in the right direction!

Thanks for the efforts to help me!
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900