windows form stops responding during non-infinite loop

Hi,I have a windows form that sends out a monthly opt in newsletter email to all
of our community members. The problem is that the list is large, and every time
I run the program it sits there appearing to be frozen. I have to watch the
program under task manager and watch its resources to see if its running, and
checking the queue mail folder for emails. This obviously is not a great way to
run the program.In my code I loop thru a sqldatareader with 10's of thousands of
records, and when its done I update the windows form with the counts of emails
sent etc.
How can I stop this form from not responding Is there something I can put in
the loop
One thing I was thinking is that the form label update only happens after the
loop is completed. Would updating it during the loops every 20 , or 50 loops
possibly help

Any advice is appreciated

Thanks very much,
Mike123


Answer this question

windows form stops responding during non-infinite loop

  • Elyasse

    sounds like spam to me

  • Leigh_d

    You can try by executing the program in different threads. That is whenerver you run the program spawn another thread which performs all the tasks. Mean time you can have progress bar at your application, which will indicate the progress level. This way your main windows form will not be frozen.

    Since your main windows form is on different thread it can respond to other functions.


  • jacobmross

    mikemike wrote:
    I loop thru a sqldatareader with 10's of thousands of
    records
    If you're looping through datareaders, you're not looping through records...you're looping through recordsets. No wonder your program is playing possum.

    With that...

    The query might not be complete and still executing but slowly displaying records as it rolls through the execution plan.

    Another cause may be the loop is trying to run faster than the query. In a struggle to dominate the allocations, they both die.

    Adamus



  • gtejeda

    mikemike,

    for responsiveness you do not need to add multiple threads. DoEvents gives time for the interface to handle updates.

    Multithreading is a not really difficult but you will have to think about how shared data is accessed. If you do not feel comfortable using it you can wait.

    As I mentioned, it could possibly increase performance as in how long it takes to complete sending to all recipients. If you are ok with the current time you should not worry about multithreading at this stage.



  • Marcio Monego

    Hi Everyone,

    I have made some changes to my code which have stopped the application from freezing. (Adamus - I added your suggestions including updating the counter in the loops -Matty4242 - I added "Application.DoEvents" as well)

    HOWEVER, because I can't keep running this program and firing out emails I had to comment out the line that actually sent out the actual email.

    Now that the program is running fun with the line commented out, do you think I still need to multithread I mainly program in ASP.NET 2.0 and have very little experience with windows forms and no experience at all with multi threading.

    Thanks very much!

    mikemike



  • Billy Sells

    andreas,

    thanks very much for the great answer. I will run this application in 2 weeks time with the send enabled.

    I'm not so worried about performance so hopefully it works ok. If it crashes I'll come back and let you knwo and maybe look further into multi threading.


    Thanks!

    mikemike


  • David Gorena Elizondo - MSFT

    If it's not broken...don't fix it

    Adamus



  • IGFET909

    i'm sending a members newsletter to 10,000's of people. Using bcc's is not a good way to deliver email newsletters if you want them getting past spam filters...

    thanks,

    mikemike


  • Lockie

    Simply try putting an "Application.DoEvents" statement inside your loop - this should allow the window to refresh and process any queued windows messages.
  • Dr. Ning

    Well Mike you have a couple of options:

    1. Add a text field or label that displays the loop counter variable so you can "see" it immediately working or not responding on your form. Just put it in the lower right hand corner.

    Do While Not rstFields.EOF

       txtMyCounter.Text += myLoopCounter

    Loop

    2. Add a progress bar which is a little more work but the same concept as #1.

    3. Instead of looping through a sqldatareader which is extremely RAM-intensive, consider calling stored procedures (using a cursor) so the hardware work is done on the SQL Server and not the web server.

    4. Make sure the connection.close is within scope so that it is closing.

    • Use Try...Catch...Finally

    5. Add another text field or label to your form called tComplete.text

    • In the last line of your procedure/function set the text property to done.
    • tComplete.Text = "Complete"

    6. As a final note, add other text fields that display out to the form at different stages in the function. This is a really good way to literally see what the function is doing and where it is dying.

    Adamus



  • platinumbay

    umm. . . why are you sending multiple emails

    send one email with your recipients in the bcc property.

    done in milliseconds!

    give your smtp server a break!



  • Ralph Depping

    Also...

    If you're dealing with bulk email, consider using distribution lists.

    If you're mail merging(using same email template but changing a few things to make it personable), consider using MS Word objects.

    By incorporating both the DL and the Word object, most of the work will be done behind the scences saving you and your program a lot of blood, sweat, and tears.

    Adamus



  • Bernhard Kirchner

    Hi Adamus,

    It's not currently broken, but I am not sure if thats because I have the this line commented out.

    'smtpClient.Send(MailMessage)

    If I bring this line live in my code do you think my application will crash again

    I am currently looping thru the sqldatareader and creating and destroying the mail object, just not sending it.

    I can't just test it and see if it crashes because I can't have people receiving emails solely because I am testing things. I am new to this multi threading I didnt think it was possible for a part of a loop to run too slow. I thought it would just wait until the line is complete

    Maybe I am missing something but this feedback from Andreas makes me think sending these emails is harder than I had initially thought.

    "If you are actually sending the mails in the loop you are probably spending most time waiting for connections and responses. It would then help to run more than 1 thread processing the mails. You will need to take concurrency and thread safety into consideration."

    any thoughts

    Thanks very much once again!

    mike


  • Satie Cheung

    Multithreading is definatly the way to go as Tarun suggests.

    http://msdn.microsoft.com/library/default.asp url=/library/en-us/cpref/html/frlrfsystemthreadingthreadstartclasstopic.asp

    However, you will not see the progress unless you update some windows form control like every 20, 50 records as you also suggest. If you do that from a process running in a new thread you have a few things to consider for beeing thread safe.

    Here is lots of resources about multithreading in windows forms.
    http://dotnet.mvps.org/dotnet/faqs/ id=multithreading&lang=en

    If you are actually sending the mails in the loop you are probably spending most time waiting for connections and responses. It would then help to run more than 1 thread processing the mails. You will need to take concurrency and thread safety into consideration.



  • windows form stops responding during non-infinite loop