1,105,581 Community Members

Proper Thread Handling

Member Avatar
Ange1ofD4rkness
Posting Whiz
312 posts since May 2010
Reputation Points: 29 [?]
Q&As Helped to Solve: 12 [?]
Skill Endorsements: 9 [?]
 
0
 

So currently I have been working with a program that is working with 2 threads, one is used to scan a webpage, download it's data, parse it, and then update a form. The other thread is responsible for running an elapsed time, that gets the elapsed running time, and then updates a label on the form.

Now currently I have it set up where each thread runs a seperate class from the main form class. I create the class, assign it some variable, and link it to a thread. Each of these have a function that looks something like this

public void run()
{
    while(stopRun == false)
    {
        if(pauseRun == false)
        {
            //do some work
        }
    }
}

What's going on here is that when I initally start the program this function is called, stopRun is set to false, and pauseRun is set to true.

This is using the concept of BusyWaiting, where this while loop is constantly running, only stopping when the program is closed (so in otherwords, when I start up the program I start the thread and this loop is running). Now on start pauseRun is set to true, and is set to false when the user hits the start button (and is set back to true when the user hits the stop button). This concept allows me to offer a play/pause concept, where data isn't lost and everything is set up.

But the problem is this seems very resource intensive on a computer. Both of the threads execute their functions (Read the website or elapsed time) on the concept of a timer function, where I use a TimeSpan check to see if so many seconds have passed (every 1 second the elapsed time is updated, every 15 seconds checks the website).

So I guess my question is, is there a more efficent way to make this concept work? I have been looking into thread timers, where I could have a timer go off, it runs the thread, and does it thing, with out this BusyWaiting that seems to be killing me CPU.

My 5 year old laptop has a dual core (Intel Core 2 Duo-T9300) and when running this its CPU usage shoot up to almost 100% when these two threads are running. Now my desktop, which I have only tested running one thread on (the readin), I am getting 16% usage (Intel i7-920). I know it's a different CPU, but that's still alot for such a simple task (I feel if I test it now with the elapsed function I see 30%+ usage)

Hope this makes sense (I am having trouble finding the right words to use), and hope to hear back

Member Avatar
Momerath
Senior Poster
3,832 posts since Aug 2010
Reputation Points: 1,327 [?]
Q&As Helped to Solve: 664 [?]
Skill Endorsements: 19 [?]
Featured
 
0
 

At the very least you should be calling Thread.SpinWait so your threads will let other stuff run while they idle. You also might consider using Monitor.Wait and Monitor.Pulse to stop/start your processes.

Member Avatar
Ange1ofD4rkness
Posting Whiz
312 posts since May 2010
Reputation Points: 29 [?]
Q&As Helped to Solve: 12 [?]
Skill Endorsements: 9 [?]
 
0
 

Hey Momerath, so I started reading about Monitors, and from what I have read it seems Montiors are used to protect the critical region. Am I reading this correctly? Or did you see some other use for Monitors that could serve my purpose?

I am not worried about protecting a critical region. When I read in the webpage, I call a static class that uses a delegate to call back to another function where it parses the data (however that call to parse data is encapsualted in a lock statement) ... I assume that's safe since it's using a mutex concept

UPDATE: I was talking with a professor today, and she was telling me to simply use Thread.Sleep() to save my resources. After I tried it, I saw a huge performance increase (I slept the one thread for 1 second, and the other I slept for just 15 milliseconds, I saw a 75% - 89% CPU usage drop on my laptop).

HOWEVER, this was only during the running processes (the if(pauseCode == false) section). It seems when the while loop is only running on its own (so the program is paused), I was going up to 50% CPU usage. So I have to ask is this a proper took to use or should I look into something else?

Am I looking at the Monitors wrong, and these are indeed what I want, whould I be using something like an AutoResetEvent (to do a sleep/wakeup), or is the Thread.Sleep() okay?

BTW, thanks for taking time to look into this

Member Avatar
Ange1ofD4rkness
Posting Whiz
312 posts since May 2010
Reputation Points: 29 [?]
Q&As Helped to Solve: 12 [?]
Skill Endorsements: 9 [?]
 
0
 

Update: I fixed the issue with the 50% usage I mentioned in the UPDATE section in my previous post (I put one of the sleep timers in the if(pauseCode == false) statement).

However would still love to hear if these sleep timers are really the correct way to go (well thread sleep)?

Member Avatar
Momerath
Senior Poster
3,832 posts since Aug 2010
Reputation Points: 1,327 [?]
Q&As Helped to Solve: 664 [?]
Skill Endorsements: 19 [?]
Featured
 
0
 

In my opinion, no, Thread.Sleep isn't the way to go. I'll post some other methods in a day or two

Member Avatar
Ketsuekiame
Posting Virtuoso
1,676 posts since May 2010
Reputation Points: 793 [?]
Q&As Helped to Solve: 231 [?]
Skill Endorsements: 27 [?]
 
0
 

You're doing a stop run and pause run; are your threads triggered by some other process? If they are, you should look into events. With events, you can subscribe to them and they will be called as and when required. This means you won't need any complex thread control code.

If not (or you can't use events for marking reasons) then perhaps AutoReset or ManualReset events would be better.

The difference between the two is basically whether or not one closes the "gate" behind itself. You can then control these wait events independently. Whilst they are nonsignalled, any threads attempted to access them (with the WaitOne method) will block. You can then signal these events to allow a thread to pass through.

Member Avatar
Ange1ofD4rkness
Posting Whiz
312 posts since May 2010
Reputation Points: 29 [?]
Q&As Helped to Solve: 12 [?]
Skill Endorsements: 9 [?]
 
0
 

The threads work as follow

Thread 1 - Periodically (around 15 secs) download data from a website, parse it, then take that data and update some Windows Form items.

Thread 2 - It just does an elapsed time effect, updating a label (there's some math on the back end, but that's the basics). This fires every second

So currently they have the sleeps, to suspend them when they aren't needed. The program only stops the threads when it closes, and starts them when it opens. However the actions they perform follow a Pause/Resume concept I guess you'd say.

The only event I could think of here would be an Event Timer. But I'll wait to see what Momerath has to say before I dive in to deep

Member Avatar
Ketsuekiame
Posting Virtuoso
1,676 posts since May 2010
Reputation Points: 793 [?]
Q&As Helped to Solve: 231 [?]
Skill Endorsements: 27 [?]
 
0
 

Yeah you could easily switch this to being Timers. Set them up to fire your download method every 15 seconds and set a second one to fire your label update every second. This will massively reduce your code complexity.

The other things I were talking about were more like mutexes. If you google for AutoResetEvent or ManualResetEvent and review the MSDN pages it should give you a basic understanding of how they work, however, I would not recommend this approach based on your requirement.

Member Avatar
Ange1ofD4rkness
Posting Whiz
312 posts since May 2010
Reputation Points: 29 [?]
Q&As Helped to Solve: 12 [?]
Skill Endorsements: 9 [?]
 
0
 

Okay so I have been busy but finally got time to look back into this.

@Ketsuekiame - I have been looking into those AutoResetEvent and ManualResetEvent as a possiblility

@Momerath - Were you able to come up with some methods by chance?

You
This article has been dead for over three months: Start a new discussion instead
Post:
Start New Discussion
Tags Related to this Article