NotifyIcon & DestroyIcon

Posted: 11/21/2006

I'm not sure why I never ran into this issue before but I incurred a decent size memory leak in a report engine that I run. The project was originally designed with .NET 1.1 and Visual Studio 2003... I later upgraded that to VS2005. Just recently, I upgraded the data objects from ADO to ADO.NET and it doing so I started a fresh VS2005 project because I noticed legacy files from the 2003 editor. All of a sudden the application began running out of virtual memory.

I pulled the task manager up and set it to view virtual memory, handles, threads, objects and gdi objects. I could have sworn my memory leak would have been with the ADO.NET connection, command or datareader and me not releasing them in the correct order but infact I was leaking memory due to an icon I was using in the system tray to indicate when the report engine was actively generating a report. (putting an icon in the system tray allows me to provide a menu that's easily accesible from an admin on the machine). Now, why this never caused an issue before I haven't put my finger on yet.... here's was my resolution though.

I found someone with a similiar issue in this thread that put me onto my solution: http://www.vbforums.com/archive/index.php/t-298369.html

I added an API declaration and the sub I updated, the leak appears to have stopped though I'll be monitoring it closely under a stress test to verify I've completely sealed it up... I still maybe leaving handles open somewhere:

    Public Declare Function DestroyIcon Lib "user32.dll" (ByVal hIcon As IntPtr) As Int32

    Private Sub UpdateSystemTray(ByVal indexOfIcon As Int16, ByVal NotifyText As String)
        Dim objBitmap As Bitmap
        Dim objIcon As Icon
        objBitmap = New Bitmap(ImageList1.Images(indexOfIcon))
        objIcon = System.Drawing.Icon.FromHandle(objBitmap.GetHicon)
        If Not (NotifyIcon1.Icon Is Nothing) Then
            DestroyIcon(NotifyIcon1.Icon.Handle)
        End If
        NotifyIcon1.Icon = objIcon
        Try
            NotifyIcon1.Text = ENGINE_ID & ": " & NotifyText
        Catch ex As Exception
            DebugError(ex.Message)
        Finally
            objBitmap.Dispose()
            objBitmap = Nothing
        End Try

    End Sub