soriega
asked on
vb timer seem to increase mem usage, how can that be stopped?
Hi. I am trying to read the color of a pixel on the computerscreen every 0.1 seconds. The problem i have is that the mem usage (seen in Windows Task Manager / processes) increases rapidly (especially when the screencolor changes) and after a while i get a system.outofmemory exception
Is there any way of clearing cache memory that is stacked or maybe someone has an even smarter solution.
Try for example this code:
Is there any way of clearing cache memory that is stacked or maybe someone has an even smarter solution.
Try for example this code:
Public Class Form1
Private Declare Function GetDC Lib "user32" Alias "GetDC" (ByVal hwnd As Integer) As Integer
Private Declare Function GetPixel Lib "gdi32" (ByVal hdc As Integer, ByVal x As Integer, ByVal y As Integer) As Integer
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Timer1.Interval = 100
Timer1.Enabled = True
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Dim testcolor As Integer
testcolor = GetPixel(GetDC(0), 100, 100)
Button1.BackColor = System.Drawing.ColorTranslator.FromOle(testcolor)
End Sub
End Class
Shouldn't you bet loading GetDC(0) into a variable and calling ReleaseDC on each timer tick?
ASKER
OK thanks. I am not to experienced on using "releaseDC" , do you have a code snipplet maybe?
If I take the shortcut of omitting error handling as an exercise for the student...
Public Class Form1
Private Declare Function GetDC Lib "user32" Alias "GetDC" (ByVal hwnd As Integer) As Integer
Private Declare Function GetPixel Lib "gdi32" (ByVal hdc As Integer, ByVal x As Integer, ByVal y As Integer) As Integer
Private Declare Function ReleaseDC Lib "user32" Alias "ReleaseDC" (ByVal hwnd As Integer, ByVal iDc As Integer) As Integer
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Timer1.Interval = 100
Timer1.Enabled = True
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Dim testcolor As Integer
Dim iDc as integer = GetDC(0)
testcolor = GetPixel(iDc, 100, 100)
ReleaseDC( 0, iDc)
Button1.BackColor = System.Drawing.ColorTransl ator.FromO le(testcol or)
End Sub
End Class
Public Class Form1
Private Declare Function GetDC Lib "user32" Alias "GetDC" (ByVal hwnd As Integer) As Integer
Private Declare Function GetPixel Lib "gdi32" (ByVal hdc As Integer, ByVal x As Integer, ByVal y As Integer) As Integer
Private Declare Function ReleaseDC Lib "user32" Alias "ReleaseDC" (ByVal hwnd As Integer, ByVal iDc As Integer) As Integer
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Timer1.Interval = 100
Timer1.Enabled = True
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Dim testcolor As Integer
Dim iDc as integer = GetDC(0)
testcolor = GetPixel(iDc, 100, 100)
ReleaseDC( 0, iDc)
Button1.BackColor = System.Drawing.ColorTransl
End Sub
End Class
Try this out:
Private Declare Function GetDesktopWindow Lib "user32" () As IntPtr
Private Declare Function GetWindowDC Lib "user32" (ByVal hwnd As IntPtr) As IntPtr
Private Declare Function ReleaseDC Lib "user32" (ByVal hwnd As IntPtr, ByVal hdc As Integer) As Integer
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Dim desktopHwnd As IntPtr = GetDesktopWindow()
Dim desktopHdc As IntPtr = GetWindowDC(desktopHwnd)
Dim testcolor As Integer = GetPixel(desktopHdc, 100, 100)
ReleaseDC(desktopHwnd, desktopHdc)
Button1.BackColor = System.Drawing.ColorTranslator.FromOle(testcolor)
End Sub
GetDC, like many graphic API calls returns a handle. If you want to release it you need that handle. I said this in the first post.
However, I wonder if the time that it takes to complete may be longer than 100ms, and if so, it may get called multiple times before the first time completes and that could cause problems.
However, I wonder if the time that it takes to complete may be longer than 100ms, and if so, it may get called multiple times before the first time completes and that could cause problems.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Yepp i am aware about the problem that it might be "stacking" of timer things. However, if i increase the timer.interval=3000 it still keeps increaseing mem usage. It seems to increase more every time the color of the pixel changes? I have implemented both these presented solutions, however none of them fixes the problem with increased memory usage.
ASKER
The easiest way to watch this problem is to open youtube.com and let the application read from a spot where the color changes on the screen. I can se Mem usage increasing slow and steady all the time...
ASKER
Here is actually a solution to the problem ! Very weird, but this actually decreases the mem usage to a minimum:
Me.WindowState = FormWindowState.Minimized
Me.WindowState = FormWindowState.Normal
Not nice and clean, but it works
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
I will try to use the Release thing. Any other things out of these where "release" style should be used?
GetWindowRect
FindWindow
mouse_event
SetWindowPos
EnumWindProc
FindWindowEx
GetWindowText
EnumChildWindows
GetWindowRect
FindWindow
mouse_event
SetWindowPos
EnumWindProc
FindWindowEx
GetWindowText
EnumChildWindows
Those APIs are "safe"... =)
ASKER
Thanks
As a follow up to your question about other API's...
I don't see any in that list that should cause you a problem.
Mainly when you get a DC, or a resource like Bitmap, Fonts or other items to "Draw" with, you select them, store their prev values, and restore that when through. Much of GDI works like this. You get it, use it and give it up or you have memory leaks.
I don't see any in that list that should cause you a problem.
Mainly when you get a DC, or a resource like Bitmap, Fonts or other items to "Draw" with, you select them, store their prev values, and restore that when through. Much of GDI works like this. You get it, use it and give it up or you have memory leaks.
Also I think GetDC may take a while and you have to ReleaseDC?
You are probably getting out of memory for not doing a ReleaseDC.
You also may be reentering the Tick event before the prev event is processed. Maybe a boolean flag that exits the tick event when set so that it doesn't process any more until it finishes the current one.
Here is an FAQ from Bob Powell on doing it in Vb.NET:
http://www.bobpowell.net/eyedropper.htm