Application.doevents memory leaks (please help!)

idealcc

New member
Joined
Apr 20, 2008
Messages
3
Programming Experience
5-10
Hi,
I have a background worker collecting xml and inserting into a SQL Express database whilst the main form must keep full responsive control. This all works fine except that my cpu usage goes from idling at about 8% to 60% when the doevents is called from within the following code:

do While Me.backgroundWorker1.IsBusy
Application.DoEvents()
End While

After putting a counter in the loop it can run about 500 iterations.

Now some of your answers to my problem may be that the code in the main form which application.doevents runs is the problem however when I debug the Application.DoEvents() line it steps into the sub defWndProc for the main form which doesn't help me find where the actual leaks are occuring?

Sometimes I could be collecting several XML messages at a time which can cause the CPU to completely lock up at 100% and then it just hangs and gives in. This happens on Vista and XP with 1 gig of memory (which is what many users have their pc's specced at)

Can anyone point me in the right direction for solving this issue?

Many Thanks
 
Thanks for your quick reply Neal,
I did try a Thread.Sleep before and tried your suggestion again but still getting the issue. In fact the sleep causes the app to not respond momentarily.

Any other thoughts?
 
It sounds like whatever code you have running in the background worker may in fact not be working properly. If you want to provide more code for review I can help better, but without seeing more it's too hard to help you with this.
 
Code

Hi Neal,
Here's the code which I have inherited from previous developers.
I've added some GC.Collects and disposing of objects but removed them because they don't seem to help.
Hopefully you may be able to make something of this for me.

Thanks, Lee

1. Do work
VB.NET:
Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, _
ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        Dim thisRace As New liveDetails
        e.Result = thisRace.getThisRaceDetails(e.Argument, TabTimeDiff)

End Sub
2. Get ThisRaceDetails
VB.NET:
Public Function getThisRaceDetails(ByRef tr As thisORace, ByVal TabTimeDiff As String) As thisORace
        Try
            If tr.raceID = "SR_20080404_03" Then
                Stop
            End If

            Dim tabKey As String = general.TABKey
            setNextCallTime()

            Dim wsRacing As New IGL.TAB_NSW.tab.racing.Racing

            ' Get the race status
            checkTimeBetweenCalls()
            Dim newInfo As New IGL.TAB_NSW.CollectRunnerInfo
            'newinfo.
            Dim thisStatus As XmlElement = wsRacing.EventRaceInfo(tabKey, "NSW", tr.raceID)
            'reset the delay for the next call.
            setNextCallTime()

            ' get the relevant data from the XML
            stripXMLstatus(thisStatus, tr.JumpTime, tr.RaceStatus)

            ' Update the data store with the jumptime and status

            'wait for it
            checkTimeBetweenCalls()
            ''Debug.WriteLine("Getting details for race: " & tr.raceID)

            If tr.RaceStatus = "Betting Open" Or tr.RaceStatus = "Open" Then
                ' ***** get the odds *****
                Dim XMLEventApproximates As Xml.XmlElement = wsRacing.EventApproximates(tabKey, "NSW", tr.raceID)
                Dim insertDivs As New IGL.DataLayer.insertEventApproximates
                Try
                    insertDivs.storeDividends(XMLEventApproximates)
                   
                Catch argEx As ArgumentException
                    tr.Error_Type = thisORace.DownloadError.NO_POOL_CHANGE
                Catch sqlEx As SqlClient.SqlException
                    tr.Error_Type = thisORace.DownloadError.DATA_EXISTS
                Catch xmlEx As Xml.XmlException
                    tr.Error_Type = thisORace.DownloadError.XML_ERROR
                Catch ex As Exception
                    tr.Error_Type = thisORace.DownloadError.UNKNOWN
                End Try

            Else
                ' ***** get the results *****
                Dim XMLEventResultsDividends As Xml.XmlElement = wsRacing.EventResultsDividends(tabKey, "NSW", tr.raceID)
                processResults(XMLEventResultsDividends, tr)

            End If
        Catch sqlEx As SqlClient.SqlException
            tr.Error_Type = thisORace.DownloadError.DATA_EXISTS
        Catch xmlEx As Xml.XmlException
            tr.Error_Type = thisORace.DownloadError.XML_ERROR
        Catch ex As Exception
            tr.Error_Type = thisORace.DownloadError.UNKNOWN
        Finally
           setNextCallTime()

        End Try

        Return tr


    End Function
3. GetLiveDetails which is where performance slows on the doevents

VB.NET:
    Public Function getLiveDetails(ByVal thisRaceID As String, ByVal _TabTimeDiff As String)
        TabTimeDiff = _TabTimeDiff
        thisRaceDetails = New thisORace(thisRaceID)

        Do While Me.BackgroundWorker1.IsBusy
            Application.DoEvents()
        Loop

        Me.BackgroundWorker1.RunWorkerAsync(thisRaceDetails)
        Do While Me.BackgroundWorker1.IsBusy
            Application.DoEvents()
        Loop

    End Function
 
How/when/why is getLiveDetails called? Looping DoEvents to check IsBusy is something you might do if you expect it to get ready immeadiately afterwards, I suggested this recently to someone that wanted to wait briefly while cancelling work to close a form. Normally you should find other ways to synchronize the work. Looping DoEvents after the RunWorkerAsync call to wait for completion is most certainly wrong, BackgroundWorker has a RunWorkerCompleted event that will notify UI thread when the work is complete. Calling DoEvents in general is a good sign to rethink the event flow and possibly look for proper threading/synchronization solutions.
 
Back
Top