Running Loop without Hogging App

How do you run a loop in a program without using up all the resources for you application.
For instance, you are trying to verify that all of the data on a spreadsheet is correct,
such as making sure the e-mail address, phone, and fax is correctly formated, on many many rows of a spread sheet. If you do this by looping for each row, the app will appear frozen and you can not update any content on the interface programatically, how do you prevent this or work around this.


Answer this question

Running Loop without Hogging App

  • albin gorkhali

    set the thread.isbackground property to true, then if the main thread is dying, it will automatically kill background threads.

    see msdn link,
    http://msdn.microsoft.com/library/default.asp url=/library/en-us/cpref/html/frlrfsystemthreadingthreadclassisbackgroundtopic.asp

  • Richard Hotchkin

    You could create another thread.

    Read in the msdn about the System.Threading namespace to understand how that works.

    Basically, it's like the stuff in your extra thread appears to run at the same time as the main thread of your application, so you can do what you want in your extra thread (in this case you're supposed to have an "endless" loop running there, until you want to leave the thread),
    without hanging the messaging of your app.

    Hope that helps, I don't have so much time right now.

  • Wayne Gibson

    Well, the easiest answer is to make the Thread Object a public variable!  =)

    Declare the Thread at the class level and instansiate it in the Button.Click event.  Then you can act on the Thread later:


    Dim t as System.Threading.Thread

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 

    t = New System.Threading.Thread(AddressOf DoWork) 
    t.Name = "MyWorkerThread" 
    t.Start() 

    End Sub 

    Now 't' is accessible from other routines in your code.

    Good luck!

  • sentonal

    Start a worker thread to do the processing in the background.  It won't finish any quicker, but your UI will remain responsive.

    Safe, Simple Multithreading in Windows Forms, Parts <a href="http://msdn.microsoft.com/library/default.asp url=/library/en-us/dnforms/html/winforms06112002.asp">1</a>, <a href="http://msdn.microsoft.com/library/default.asp url=/library/en-us/dnforms/html/winforms08162002.asp">2</a>, and <a href="http://msdn.microsoft.com/library/default.asp url=/library/en-us/dnforms/html/winforms01232003.asp">3</a>

  • lushaohua

    Actually, these are all great suggestions!  I'd just like to state that the original poster should read the tutorials linked above to msdn's simple multithreading articles because one of the issues with multi-threading is the call back to the UI.

    The reason I bring this up is because I feel it's bad practice for a thread to directly alter the UI if you're incorporating a worker thread.  I like the way the article is based of delegates for the task of separating the UI and the Worker thread.  Another quirk is that this one time, it may not be necessary to have a callback, but as you progress in windows forms, that call back is definitely important to your application.  Especially if you have events and/or functionality that relies on it.  

    I'm not a big fan of timers for this case.  Especially since the beginning and end of the loop are predetermined.  If a loop is based on a spreadsheet, it will have an end sooner or later.  For this particular case, it's better with that worker thread, and maybe showing a cancel button.  Furthermore, having the mouse icon become the hourglass is a good practice so you don't end up having the user click like crazy wondering what is going on.  Even if you use a status bar or change some label, you'd be surprised how stupid users are, and will miss it completely.  Spawning a series of crazy threads should be avoided.  Multi-threading shouldn't be handled lightly, and extreme caution is suggested to avoid wasting the instructions to the cpu unnecessarily.

  • Lucc

    Multi-threading is a viable answer, depending on what else the user will be doing while the secondary thread runs.

    A simple multi-thread example is as follows:

    Say you have a button you click that executes your long processing routine:

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    'Do a massive code loop
    For Each Row in MySheet.Rows

    [Processing...]

    Next

        End Sub

    To execute your code in another thread, move the code to its own subroutine and create a new thread at the address of that sub in the Button.Click event:


    Private Sub DoWork()

    'Do a massive code loop
    For Each Row in MySheet.Rows

    [Processing...]

    Next

    End Sub


        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

            Dim t As New System.Threading.Thread(AddressOf DoWork)
            t.Name = "MyWorkerThread"
            t.Start()

        End Sub


    Now the code in DoWork will run in a seperate thread and not block your application.  Use custom events and public variables to communicate between threads if necessary.

  • jeff_stone

    There is another solution that does not require multiple threads and eliminates the need for locks. It works well if you can divide the work into small units.

    Instead of writing a loop, create a data structure (class) containing the state you will need while performaing your lengthy operation. You may have current row, for example, for a spreadsheet.

    When the action is initiated, start a windows.forms.timer. On the tick event, perform a small unit of work (one row), and update the state information in your class (next row). Continue the timer until all the work is done, then stop it.

    Sometimes locking can be a hassle with multiple threads. There is no locking required with a timer, but you do need to make sure your state (current row) does not become invalid (row deleted).

  • J.Z

    awesome rkimble
    that is exactly what i was looking for.

    Also is there any way to stop this thread now that it is going
    like say the user closes the window...
    i can figure out where to put the command.
    but how do i get that thread since it is not a public variable

    i know to stop it i will need to do the abort command but how do i capture that thread
    or for that matter how do i ensure that they dont click the button again and start another new process.

  • Running Loop without Hogging App