?
Solved

c# - How to refresh form while waiting on process - Maybe Threading?

Posted on 2008-11-04
10
Medium Priority
?
6,126 Views
Last Modified: 2013-12-17
Greetings,

I have a C# app, which tests for connectivity by pinging a server.

When I start the ping processes, I also start a series of 8 cycling graphics that I want to use to show that the application is "processing" and not "hung".

Right before I start the routine for pinging, I start another routine which is used to process the graphics, basically it is a timer control which is set to unhide 1 graphic at a time, in a series of 8, then rehide it, and on the next pass through the timer, the next graphic would unhide, then rehide, etc. (showing motion)

The graphics come up ok, but when the main routine goes to do it's ping, especially noticable on pings that don't reply, the graphic animation doesn't repaint at all until the ping response or failure has come back.

My guess is that I will need to handle the refresh via a second thread, but I don't have a clue how to go about doing that. I've spent the last couple of days trying to read and figure out threading, but am having a tough time of it.

Basically, what I want to be able to do, is:

sequence of events:

1) other code runs from before the ping events
2) a second thread starts, which cycles through the images, and does the refresh's on the main threads form (which would show the animation of the graphics)
3) the ping events would then fire off, and process.
4) after the ping events are ALL done... the second thread (which was used to do the refresh's of the main threads form, would then be terminated. (the second thread terminated, not the main thread)

I am very new to c# but am learning VERY quickly. I'm a "look at working code, and disect it to figure it out" kind of learner, so if someone could help me with how to accomplish this, I would be very appreciative.

Thanks!
0
Comment
Question by:MiSheps
  • 5
  • 4
10 Comments
 
LVL 16

Assisted Solution

by:CuteBug
CuteBug earned 2000 total points
ID: 22882784
This link will give you a better understanding of threading
http://www.albahari.com/threading/
0
 
LVL 16

Assisted Solution

by:CuteBug
CuteBug earned 2000 total points
ID: 22882792
This should be your sequence

1) start the pinging events "on a separate thread"
2) a second thread starts, which cycles through the images, and does the refresh's on the main threads form (which would show the animation of the graphics)
    For this you have to use Control.Invoke
3) After the Pinging events terminate, terminate the second thread

This way your main application thread will be free to handle its own events and you will get an application that doesn't freeze up while pinging.
0
 
LVL 64

Expert Comment

by:Fernando Soto
ID: 22882804
Hi MiSheps;

Have a look a the BackgroundWorker component which spins off a new thread and make threading a little easier.

http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker_members.aspx

If you post the code that does the pinging to the other system I may be able to help a little more.

Also when working with thread the only thread that is allowed to modify the values of controls on the GUI is the thread that created it which means that the new threads can not modify controls directly.

Fernando

0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 

Author Comment

by:MiSheps
ID: 22883184
Thank you for responding guys!

I didn't think about doing the pinging from the new thread... but that makes perfect sense now that I think about it.

So, my question would be, how do I go about doing the following:

1) As part of my ping process, I update a label on my main form to reflect "good ping" or "bad ping" after I determine success, or failure of the ping. How would I update this information on the main form from the secondary thread?

2) What is the proper way to use the invoke process?
0
 
LVL 16

Assisted Solution

by:CuteBug
CuteBug earned 2000 total points
ID: 22883223
0
 

Accepted Solution

by:
MiSheps earned 0 total points
ID: 22883596
CuteBug,

I have chosen to do it a little differently and wanted to run the thought by you. It seems to be working very well this way, but not sure how "clean" the code is.

What I'm doing is:

1) Main code runs
2) When the code gets to the part where it does the network test, it first kicks off a timer, (in the main form's natural thread) which cycles, creating the graphics animation.
3) Then the code starts a second thread, which does the actual pinging processes. (as you suggested).
4) The next step in the main form (natural primary thread) is that it kicks off another timer which has the following in it:

    private void timer4_Tick(object sender, EventArgs e)
    {
        if (lblNetworkTestOther.BackColor == System.Drawing.Color.LightGreen)
        {
            CheckForPingResults();
        }
        if (lblNetworkTestOther.BackColor == System.Drawing.Color.Red)
        {
            CheckForPingResults();
        }
    }

So basically what it is doing is cycling through, waiting for the lblNetworkTestOther.BackColor to change to either Red, or LightGreen (As part of the process of the second thread that we kicked off, after it gets back either a success or failure from the ping, it changes the backcolor of the label to reflect a good, or bad response (green=good, red=bad).

So, because the primary thread is in a loop, waiting for the second thread to update the label on the main form's background color to either green or red before it continues, it keeps the application from getting ahead of itself.

Then, once the secondary thread finishes, it should auto-close (I think?) itself. and then the process continues in the primary thread:

5) Code stops the timer that is waiting for the label color change and moves on to the next process
6) code stops the timer which controls the animation functionality of the graphic
7) code hides the panel that the animation graphic is contained in
8) the rest of the code for addional testing runs.

So, in doing it this way, isn't it similiar to using an invoke? Is there an advantage of using invoke, vs. the way that I've done, or an advantage of handling it the way I am doing now?

Thanks for your help with this one! I'm learning a TON from this experience!









0
 
LVL 16

Assisted Solution

by:CuteBug
CuteBug earned 2000 total points
ID: 22883678
The main purpose of using Invoke is to access a WinForm control from a thread in which it was not created.
Normally when you add a control to a WinForm, the control is created in the Main thread.
So if you start a new thread from the primary thread and you want to access the control from the second thread, then using the Invoke method is safe.
Otherwise, the control will throw an exception.

What you are doing above is also a good approach.
0
 

Author Comment

by:MiSheps
ID: 22883703
ahh, so when I do my next part, I will likely have to use an invoke then, if I understand you right...

The next part I have to fix is a similiar function to the ping, but this one grabs all data about the network cards, populates a datagrid, and then populates a few text boxes.

I have another open thread on that part if you would like to take a look at it. (Right now I'm leaving that thread open hoping to get some feedback from experts on whether or not the code that I build is worth its weight, or if it is junk - My first attempt at using WMI's in C#)

The link for it is:

http://www.experts-exchange.com/Programming/Languages/.NET/Visual_CSharp/Q_23866893.html

I of course am going to be awarding you the points for this thread, you have been very helpful! If  you would like to take a look at the other thread, and let me know what you think, like, would change, etc, I still have to award the points to someone on that thread. (no one really responded much to it)

Thanks again!
0
 
LVL 16

Expert Comment

by:CuteBug
ID: 22883818
I think your second thread question has already been answered by experts.
What you are doing is correct.
0
 

Author Comment

by:MiSheps
ID: 22884434
Thank you for your help CuteBug!
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
Hello there! As a developer I have modified and refactored the unit tests which was written by fellow developers in the past. On the course, I have gone through various misconceptions and technical challenges when it comes to implementation. I would…
Screencast - Getting to Know the Pipeline
Look below the covers at a subform control , and the form that is inside it. Explore properties and see how easy it is to aggregate, get statistics, and synchronize results for your data. A Microsoft Access subform is used to show relevant calcul…
Suggested Courses

862 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question