473,387 Members | 1,483 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Thread.Resume is Obsolete? How are we supposed to wake up SleepingThreads now?

I have a thread that sleeps for 5 minutes once it's finished running a
method and then it repeats itself if it's supposed to (bool = true).
Prior to 2.0 I was able to resume the thread after marking the bool to
false which would cause the thread to finish what it was doing and
complete, or to wake up for it's sleep state and not loop back into
itself anymore.

How do we tell a thread to stop sleeping now that Thread.Resume is obsolete?
Dec 5 '05 #1
17 5626
Benny Raymond wrote:
I have a thread that sleeps for 5 minutes once it's finished running a
method and then it repeats itself if it's supposed to (bool = true).
Prior to 2.0 I was able to resume the thread after marking the bool to
false which would cause the thread to finish what it was doing and
complete, or to wake up for it's sleep state and not loop back into
itself anymore.

How do we tell a thread to stop sleeping now that Thread.Resume is obsolete?


You use Monitor.Wait/Pulse or WaitHandles, which is what you should
have been doing before :)

See http://www.pobox.com/~skeet/csharp/t...eadlocks.shtml (half
way down) for a sample of this.

Jon

Dec 5 '05 #2
Also dont use Thread::Suspend().
http://joehacker.blogspot.com/2005/1...nd-method.html

Ab.
http://joehacker.blogspot.com

"Benny Raymond" <be***@pocketrocks.com> wrote in message
news:O2****************@TK2MSFTNGP14.phx.gbl...
I have a thread that sleeps for 5 minutes once it's finished running a
method and then it repeats itself if it's supposed to (bool = true).
Prior to 2.0 I was able to resume the thread after marking the bool to
false which would cause the thread to finish what it was doing and
complete, or to wake up for it's sleep state and not loop back into
itself anymore.

How do we tell a thread to stop sleeping now that Thread.Resume is

obsolete?
Dec 6 '05 #3
That's fine, however the thing you showed me is still sleeping - I need
to be able to wake up the sleeping thread, or terminate it (is that when
abort comes into play?)

Basically what I need to do is this:

* ClientA needs to be run every 5 minutes
* If SettingX changes to false, it allows ClientA to finish running
(if it's currently running) but it will no longer run again.
* If SettingX changes to true, it tells ClientA to start back up on
it's 5 minute cycle again.
* If App closes, it allows ClientA to finish running (if it's
currently running) but it will no longer run again.

What I was doing before (which I can see why it's wrong now but not how
to do it correctly):
* ClassX creates ClientA class
* ClassX sets loop_bool in ClientA to true
* ClassX starts ClientA thread
* ClientA thread runs and sleeps at the end
* When ClientA is done sleeping it loops, checks the loop_bool and
continus running if loop_bool is true.
* SettingX in ClassX changes
* ClassX sets loop_bool in ClientA to false
* ClassX Resumes ClientA thread
* ClassX Joins ClientA
* ClientA finishes and doesn't loop
* ClassX checks setting to see if it's true, if so it starts up the
ClientA thread again
Please help me.. haha :)

~Benny
Jon Skeet [C# MVP] wrote:
Benny Raymond wrote:
I have a thread that sleeps for 5 minutes once it's finished running a
method and then it repeats itself if it's supposed to (bool = true).
Prior to 2.0 I was able to resume the thread after marking the bool to
false which would cause the thread to finish what it was doing and
complete, or to wake up for it's sleep state and not loop back into
itself anymore.

How do we tell a thread to stop sleeping now that Thread.Resume is obsolete?

You use Monitor.Wait/Pulse or WaitHandles, which is what you should
have been doing before :)

See http://www.pobox.com/~skeet/csharp/t...eadlocks.shtml (half
way down) for a sample of this.

Jon

Dec 6 '05 #4
Benny Raymond wrote:
That's fine, however the thing you showed me is still sleeping - I need
to be able to wake up the sleeping thread, or terminate it (is that when
abort comes into play?)


You need to look through the example more carefully. The *producing*
thread is sleeping - the *consuming* thread is waiting.

The producing thread is only sleeping in order to simulate "things
happening" (processing, whatever). It's unimportant from the example's
point of view. Wait/Pulse is the important part here - you can give a
timeout to Wait, so that it will return either when the timeout has
elapsed or when the monitor is pulsed.

Jon

Dec 6 '05 #5
So what you're saying is that I should use Wait as if I was using Sleep
- and use Pulse to wake that Wait state up? That brings me to another
question however which is, how can I make sure that the thread is
Waiting before I pulse it, and how can I make sure the pulse gets there
in that circumstance? Hopefully this is clear if you look at the steps
I posted prior to your last message?

Jon Skeet [C# MVP] wrote:
Benny Raymond wrote:
That's fine, however the thing you showed me is still sleeping - I need
to be able to wake up the sleeping thread, or terminate it (is that when
abort comes into play?)

You need to look through the example more carefully. The *producing*
thread is sleeping - the *consuming* thread is waiting.

The producing thread is only sleeping in order to simulate "things
happening" (processing, whatever). It's unimportant from the example's
point of view. Wait/Pulse is the important part here - you can give a
timeout to Wait, so that it will return either when the timeout has
elapsed or when the monitor is pulsed.

Jon

Dec 6 '05 #6
Nevermind, I looked back over it again with a clean head and it's only
waiting if nothing is in the queue, which means that if I pulse it after
adding to the queue things will be ok... So if you don't mind could you
look at this pseudo code for me?

class clientMonitor
{
myClient is a "client" from class client

function main
{
initialize myClient
if (run_client_global_setting is true) then myClient.Run
}

function updateClient (gets called in cases when
run_client_global_setting changes, or main form closes, etc)
{
if (run_client_global_setting is true) then
set myClient.keep_running to true
else
set myClient.keep_running to false

Lastly run the function client.Run
}
}

class client
{
locker is a readonly object
queue is a Queue
keep_running is a boolean

function Run (something)
{
Lock the listLock object
add object "something" to Queue stack
if queue's count == 1, pulse locker
Unlock listlock object
}

function client_runner
{
loop if keep_running is true
{
Run client function that takes a few seconds to complete, then...

Lock the listLock object
if the queue has no items in it, Wait on listlock until pulsed
or until 5 minutes is up
Unlock listlock object
}
}

}



Benny Raymond wrote:
So what you're saying is that I should use Wait as if I was using Sleep
- and use Pulse to wake that Wait state up? That brings me to another
question however which is, how can I make sure that the thread is
Waiting before I pulse it, and how can I make sure the pulse gets there
in that circumstance? Hopefully this is clear if you look at the steps
I posted prior to your last message?

Jon Skeet [C# MVP] wrote:
Benny Raymond wrote:
That's fine, however the thing you showed me is still sleeping - I need
to be able to wake up the sleeping thread, or terminate it (is that when
abort comes into play?)


You need to look through the example more carefully. The *producing*
thread is sleeping - the *consuming* thread is waiting.

The producing thread is only sleeping in order to simulate "things
happening" (processing, whatever). It's unimportant from the example's
point of view. Wait/Pulse is the important part here - you can give a
timeout to Wait, so that it will return either when the timeout has
elapsed or when the monitor is pulsed.

Jon

Dec 6 '05 #7
is Monitor.Pulse actually like a enqueue and Monitor.Wait like a dequeue
except that if you give it a timeout it doesn't dequeue?

Jon Skeet [C# MVP] wrote:
Benny Raymond wrote:
That's fine, however the thing you showed me is still sleeping - I need
to be able to wake up the sleeping thread, or terminate it (is that when
abort comes into play?)

You need to look through the example more carefully. The *producing*
thread is sleeping - the *consuming* thread is waiting.

The producing thread is only sleeping in order to simulate "things
happening" (processing, whatever). It's unimportant from the example's
point of view. Wait/Pulse is the important part here - you can give a
timeout to Wait, so that it will return either when the timeout has
elapsed or when the monitor is pulsed.

Jon

Dec 6 '05 #8
Ok... after some more messing around with it i've come up with this...
Do I still have the wrong idea?

Class A
{
// non related threading stuff....
// at some point
B _client = new B();
Thread _clientThread = null;
// end non related threading stuff...

public void RunMacro()
{
if (_prefrences.Enable)
{
StopMacro(); // stop just incase we're currently running.
_clientThread = new Thread(new ThreadStart(_client.ClientThead));
_clientThread.Name = "ClientThread " +
_clientThread.ManagedThreadId.ToString();
_clientThread.Start();
}
}

public void StopMacro()
{
try
{
if (_clientThread != null &&
_clientThread.ThreadState ==
System.Threading.ThreadState.Running)
{
// tell it not to run anymore
_client.KEEP_RUNNING = false;

// Add a pulse just to make sure it stops waiting
_client.PulseClient();

// join and let it finish running
_clientThread.Join();
}
}
catch (Exception) { }
}
}

Class B
{
// more code unrelated
// at some point:
public bool KEEP_RUNNING = false;
private readonly object locker = new object();
// end more code unrelated

public void PulseClient()
{
lock (locker)
{
Monitor.Pulse(locker);
}
}

public void ClientThead()
{
int i = 5 * 60 * 1000;
lock (locker)
{
while (KEEP_RUNNING)
{
if (_prefrences.Enable)
{
// RunClient will return 5min or 20min
i = RunClient();
}
Monitor.Wait(locker, i);
}
}
}

private int RunClient()
{
// do a bunch of stuff...
if ({some expression})
return 5 * 60 * 1000;
else
return 20 * 60 * 1000;
}
}
Dec 6 '05 #9
Benny Raymond <be***@pocketrocks.com> wrote:
is Monitor.Pulse actually like a enqueue and Monitor.Wait like a dequeue
except that if you give it a timeout it doesn't dequeue?


If anything, it's the other way round - you *could* think of
Monitor.Wait as adding a thread to a queue of threads to be pulsed,
although I don't believe the ordering of pulsing is guaranteed.

It's not a terribly helpful way of thinking about it though. Think of
it as a thread watching a reference to see when a light goes on (or
something like that). Pulse flashes that light.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Dec 7 '05 #10
Benny Raymond <be***@pocketrocks.com> wrote:
Ok... after some more messing around with it i've come up with this...
Do I still have the wrong idea?


<snip>

No, that's mostly correct. A few problems though:

1) KEEP_RUNNING needs to be volatile, or you need to lock access to it.
See http://www.pobox.com/~skeet/csharp/t...latility.shtml for
more details on that.

2) Don't use _clientThread.ThreadState - just join the thread if it's
non-null.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Dec 7 '05 #11
The ordering of pulsing isn't guaranteed, but is the fact that a pulse
went out and hasn't been recieved yet guaranteed? Since I'm only using
two threads, one that waits and one that pulses wouldn't it be ok to
assume that every time I pulse, the wait block is going to hit it at
some point? The reason I ask this is that I need to pulse without
knowing where the client thread is, and if it's not waiting I don't want
it to wait once it gets to the waiting state (since i've already pulsed it).

Does that all make sense?

BTW: thanks a ton - app is already running a lot better.

Jon Skeet [C# MVP] wrote:
Benny Raymond <be***@pocketrocks.com> wrote:
is Monitor.Pulse actually like a enqueue and Monitor.Wait like a dequeue
except that if you give it a timeout it doesn't dequeue?

If anything, it's the other way round - you *could* think of
Monitor.Wait as adding a thread to a queue of threads to be pulsed,
although I don't believe the ordering of pulsing is guaranteed.

It's not a terribly helpful way of thinking about it though. Think of
it as a thread watching a reference to see when a light goes on (or
something like that). Pulse flashes that light.

Dec 7 '05 #12
Ok... just changed that in the code as well...

Jon Skeet [C# MVP] wrote:
Benny Raymond <be***@pocketrocks.com> wrote:
Ok... after some more messing around with it i've come up with this...
Do I still have the wrong idea?

<snip>

No, that's mostly correct. A few problems though:

1) KEEP_RUNNING needs to be volatile, or you need to lock access to it.
See http://www.pobox.com/~skeet/csharp/t...latility.shtml for
more details on that.

2) Don't use _clientThread.ThreadState - just join the thread if it's
non-null.

Dec 7 '05 #13
Benny Raymond wrote:
The ordering of pulsing isn't guaranteed, but is the fact that a pulse
went out and hasn't been recieved yet guaranteed? Since I'm only using
two threads, one that waits and one that pulses wouldn't it be ok to
assume that every time I pulse, the wait block is going to hit it at
some point? The reason I ask this is that I need to pulse without
knowing where the client thread is, and if it's not waiting I don't want
it to wait once it gets to the waiting state (since i've already pulsed it).


If you pulse when no thread is waiting, it's a no-op. That's the big
difference between a monitor and a semaphore. If you need that kind of
behaviour, you should look at ManualResetEvent and AutoResetEvent
instead.

Jon

Dec 7 '05 #14
I'm looking into AutoRaiseEvent and it seems like I only have to change
a couple lines of code - however when I give a timeout to the .WaitOne
it requires an exit context... What does it all mean?
"exitContext
true to exit the synchronization domain for the context before the wait
(if in a synchronized context), and reacquire it afterward; otherwise,
false.
"

Jon Skeet [C# MVP] wrote:
Benny Raymond wrote:
The ordering of pulsing isn't guaranteed, but is the fact that a pulse
went out and hasn't been recieved yet guaranteed? Since I'm only using
two threads, one that waits and one that pulses wouldn't it be ok to
assume that every time I pulse, the wait block is going to hit it at
some point? The reason I ask this is that I need to pulse without
knowing where the client thread is, and if it's not waiting I don't want
it to wait once it gets to the waiting state (since i've already pulsed it).

If you pulse when no thread is waiting, it's a no-op. That's the big
difference between a monitor and a semaphore. If you need that kind of
behaviour, you should look at ManualResetEvent and AutoResetEvent
instead.

Jon

Dec 7 '05 #15
Benny Raymond <be***@pocketrocks.com> wrote:
I'm looking into AutoRaiseEvent and it seems like I only have to change
a couple lines of code - however when I give a timeout to the .WaitOne
it requires an exit context... What does it all mean?
"exitContext
true to exit the synchronization domain for the context before the wait
(if in a synchronized context), and reacquire it afterward; otherwise,
false.
"


Unless you're using synchronization domains explicitly (and unless you
know you are, you aren't!) you can just pass in false.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Dec 7 '05 #16
Great... Ok, so this is what i'm doing now (one of the many places - i
went through today and fixed all of the areas where I was using threads
wrong). Let me know if I've finally got the right idea?
Class A
{
// stuff not needed...
// at some point _client is Class B
// On to the threading stuff:

public override void RunMacro()
{
if (_prefrences.Enable)
{
StopMacro(); // stop just incase we're currently running.

_client.KEEP_RUNNING = true;
_clientThread = new Thread(new ThreadStart(_client.ClientThead));
_clientThread.Name = "Taskulon5000 ClientThread " +
_clientThread.ManagedThreadId.ToString();
_clientThread.Start();
_client.SignalClient();
}
}

public override void StopMacro()
{
try
{
_client.KEEP_RUNNING = false; // tell it not to run anymore
if (_clientThread != null &&
(_clientThread.ThreadState == System.Threading.ThreadState.Running ||
_clientThread.ThreadState ==
System.Threading.ThreadState.WaitSleepJoin))
{
_client.SignalClient(); // Add a signal to make sure it stops waiting
_clientThread.Join(); // join and let it finish running
}
}
catch (Exception) { }
}
}
Class B
{
public volatile bool KEEP_RUNNING = false;
private AutoResetEvent autoEvent;
// other stuff...
// then..
public void SignalClient()
{
Debug.WriteLine("SignalClient");
autoEvent.Set();
}

public void ClientThead()
{
Debug.WriteLine("ClientThead");
int i = 5;
while (KEEP_RUNNING)
{
Debug.WriteLine(string.Format("Will wait {0} milliseconds", i),
"ClientThead");
bool a = autoEvent.WaitOne(i, false);
Debug.WriteLine(string.Format("Finished Waiting based on: {0}",
a ? "Signaled" : "Timeout"), "ClientThead");
if (_prefrences.Enable && KEEP_RUNNING)
{
i = RunClient();
}
else
{
KEEP_RUNNING = false;
}
}
}
}
Dec 7 '05 #17
Benny Raymond <be***@pocketrocks.com> wrote:
Great... Ok, so this is what i'm doing now (one of the many places - i
went through today and fixed all of the areas where I was using threads
wrong). Let me know if I've finally got the right idea?


<snip>

Sorry it's been so long.

1) I still wouldn't use the ThreadState to test whether it's running or
not. Just Join the thread - if it's finished, the call will just return
immediately, and signalling the client isn't going to cause any
problems.

2) I wouldn't have KEEP_RUNNING as a public field - I'd make it a
property. I'd also try to use the normal .NET naming conventions

3) Catching Exception and not doing anything with it is almost always a
bad idea - if something goes wrong, you won't have any record of it. At
the very least, log it somewhere.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Dec 12 '05 #18

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Muscha | last post by:
Hello, I have a thread that in the middle of the execution I did Thread.Sleep(). How do I tell this thread to abort it sleep and continues? Is there a way? thanks, /m
7
by: Ram | last post by:
Hi, I have two threads, one parent thread containing UI and a child thread waiting for some events from the parent thread. Now, I have two issues: 1) to keep the child thread active till the end...
7
by: Charles Law | last post by:
My first thought was to call WorkerThread.Suspend but the help cautions against this (for good reason) because the caller has no control over where the thread actually stops, and it might have...
2
by: juky | last post by:
Hi all, I have a loop in the thread checking for a particular service status, whenever the status changes to "stopped" a RaiseEvent is generated by thread and another function runs. At the same...
6
by: Buddy Home | last post by:
Hello, I want to understand whats the best way to write code to replace Thread.Suspend, Thread.Resume and Thread.Abort. I have lots of code calling these existing methods and want to minimize...
4
by: wanwan | last post by:
I'm using Microsoft Visual Studio 2005 in multithreading, I want to be able to pause and resume a thread. I see that suspend and resume are deprecated. So what can I use instead.
3
by: ercastro | last post by:
I am a new user of Visual Basic. I am currently using VB 2005. I am running a time-consuming task on the built-in BackgroundWorker() control of VB. I am using nested loops and sometimes I need...
3
by: =?Utf-8?B?TWFyayBDaGFubmluZw==?= | last post by:
I have a code which registers all threads with a thread dump class. At intervals this thread dump class will dump the stack trace of all threads. As calling StackTrace(threadtoDump) from a...
20
by: cty0000 | last post by:
I have some question.. This is my first time to use thread.. Following code does not have error but two warring The warring is Warning 2 'System.Threading.Thread.Suspend()' is obsolete:...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.