Thread Question: Sleeping thread changes to stopped on its own.

  • Thread starter Thread starter Alvin Bruney
  • Start date Start date
A

Alvin Bruney

I'm observing that a sleeping thread changes to stopped after a while. Is
that accepted framework behavior for web applications?

My thread basically does some work, and sleeps for 60 minutes before calling
itself recursively, which means it is supposed to run on the hour every
hour. But it automatically stops after 2 hours. I only get 2 emails, 1 per
hour and then nothing. When I examine the threadstate during run-time, it
has changed from background, waitsleepjoin to stopped. I'm just letting the
app sit there so I know nothing else is going on in the background. Here's
the code.

//I manually start the thread when the application launches
RateManager.GateKeeper worker = new
RateManager.GateKeeper("localhost",System.Configuration.ConfigurationSetting
s.AppSettings["toEmail"],System.Configuration.ConfigurationSettings.AppSetti
ngs["fromEmail"],"GateKeeper is initializing","GateKeeper Init");

//maintain a global handle so that i can examine thread behavior at runtime

GlobalRateMan.GateKeeperMonitor = new Thread (new ThreadStart
(RateManager.GateKeeper.Analyze));

GlobalRateMan.GateKeeperMonitor.Priority = ThreadPriority.Lowest;

GlobalRateMan.GateKeeperMonitor.Name = "GateKeeper";

GlobalRateMan.GateKeeperMonitor.IsBackground= true;

GlobalRateMan.GateKeeperMonitor.Start();

//change the text on the button to paused - webding font

GateKeeper.Text = ";";

GateKeeper.ToolTip =
RateManager.GlobalRateMan.GateKeeperMonitor.ThreadState.ToString();


//here is Analyze
Email(); //usual email code

System.Threading.Thread.Sleep(TimeSpan.FromMinutes(Double.Parse(GlobalRateMa
n.GateKeeperSleepTime))); //60 minutes

RateManager.GateKeeper.Subject = "GateKeeper is preparing to run Analysis
from Netapp-1";

[snip]

//work gets done here

//recursion controlled by sleeptime

Analyze();

When I examine the state of the thread thru the
GlobalRateMan.GateKeeperMonitor handle which is a static handle holding the
address of the thread,

it is stopped after about 2 hours. On another related note, I am noticing
other weird behavior like this thread will refuse to email if it is started
from the application_start event.
 
Alvin Bruney said:
I'm observing that a sleeping thread changes to stopped after a while. Is
that accepted framework behavior for web applications?

My thread basically does some work, and sleeps for 60 minutes before calling
itself recursively, which means it is supposed to run on the hour every
hour. But it automatically stops after 2 hours. I only get 2 emails, 1 per
hour and then nothing. When I examine the threadstate during run-time, it
has changed from background, waitsleepjoin to stopped. I'm just letting the
app sit there so I know nothing else is going on in the background. Here's
the code.

It sounds like there's a fault in your recursion. Could you produce a
short but complete example which demonstrates the problem?
 
Yeah, this doesn't sound like an obvious use of recursion. Most
applications that would use Sleep in this way would be iterative, inside a
while(true) loop. Put some code out here that shows the problem.

Also, try lowering your Sleep time and see if it drops out after two
recursions, after two hours, or if it keeps going.
 
Hi,

I don't really know what's wrong with your code. But is there a specific
reason why you use recursion ?

Recursion:
An A=method n=invocation nr

A0 calls A
A1 calls A
A2 calls A
A3 doesn't call A
cleanup A3->A2->A1->A0

Since cleanup is delayed, it causes an overhead. And recursion can only
work well if at a certain point the function doesn't call itself anymore.

I would not use recursion in your case.

Do you have a try/catch inside Analyse ?

HTH
greetings




Alvin Bruney said:
I'm observing that a sleeping thread changes to stopped after a while. Is
that accepted framework behavior for web applications?

My thread basically does some work, and sleeps for 60 minutes before calling
itself recursively, which means it is supposed to run on the hour every
hour. But it automatically stops after 2 hours. I only get 2 emails, 1 per
hour and then nothing. When I examine the threadstate during run-time, it
has changed from background, waitsleepjoin to stopped. I'm just letting the
app sit there so I know nothing else is going on in the background. Here's
the code.

//I manually start the thread when the application launches
RateManager.GateKeeper worker = new
RateManager.GateKeeper("localhost",System.Configuration.ConfigurationSettings.AppSettings["toEmail"],System.Configuration.ConfigurationSettings.AppSetti
ngs["fromEmail"],"GateKeeper is initializing","GateKeeper Init");

//maintain a global handle so that i can examine thread behavior at runtime

GlobalRateMan.GateKeeperMonitor = new Thread (new ThreadStart
(RateManager.GateKeeper.Analyze));

GlobalRateMan.GateKeeperMonitor.Priority = ThreadPriority.Lowest;

GlobalRateMan.GateKeeperMonitor.Name = "GateKeeper";

GlobalRateMan.GateKeeperMonitor.IsBackground= true;

GlobalRateMan.GateKeeperMonitor.Start();

//change the text on the button to paused - webding font

GateKeeper.Text = ";";

GateKeeper.ToolTip =
RateManager.GlobalRateMan.GateKeeperMonitor.ThreadState.ToString();


//here is Analyze
Email(); //usual email code

System.Threading.Thread.Sleep(TimeSpan.FromMinutes(Double.Parse(GlobalRateMa
n.GateKeeperSleepTime))); //60 minutes

RateManager.GateKeeper.Subject = "GateKeeper is preparing to run Analysis
from Netapp-1";

[snip]

//work gets done here

//recursion controlled by sleeptime

Analyze();

When I examine the state of the thread thru the
GlobalRateMan.GateKeeperMonitor handle which is a static handle holding the
address of the thread,

it is stopped after about 2 hours. On another related note, I am noticing
other weird behavior like this thread will refuse to email if it is started
from the application_start event.
 
No, that's not the idea.
Main thread spawns child thread. Child thread calls method. Method sleeps,
wakes up does some work, calls itself (Method sleeps, wakes up does some
work, calls itself...)

why use recursion? because it easily accomplishes what i'm after with my
tite deadline.
The recursion looks like this
Method()
{
Thread.Sleep(60);
//do work
Method();
}


Jhon said:
Hi,

I don't really know what's wrong with your code. But is there a specific
reason why you use recursion ?

Recursion:
An A=method n=invocation nr

A0 calls A
A1 calls A
A2 calls A
A3 doesn't call A
cleanup A3->A2->A1->A0

Since cleanup is delayed, it causes an overhead. And recursion can only
work well if at a certain point the function doesn't call itself anymore.

I would not use recursion in your case.

Do you have a try/catch inside Analyse ?

HTH
greetings




Alvin Bruney said:
I'm observing that a sleeping thread changes to stopped after a while. Is
that accepted framework behavior for web applications?

My thread basically does some work, and sleeps for 60 minutes before calling
itself recursively, which means it is supposed to run on the hour every
hour. But it automatically stops after 2 hours. I only get 2 emails, 1 per
hour and then nothing. When I examine the threadstate during run-time, it
has changed from background, waitsleepjoin to stopped. I'm just letting the
app sit there so I know nothing else is going on in the background. Here's
the code.

//I manually start the thread when the application launches
RateManager.GateKeeper worker = new
RateManager.GateKeeper("localhost",System.Configuration.ConfigurationSettings.AppSettings["toEmail"],System.Configuration.ConfigurationSettings.AppSetti
ngs["fromEmail"],"GateKeeper is initializing","GateKeeper Init");

//maintain a global handle so that i can examine thread behavior at runtime

GlobalRateMan.GateKeeperMonitor = new Thread (new ThreadStart
(RateManager.GateKeeper.Analyze));

GlobalRateMan.GateKeeperMonitor.Priority = ThreadPriority.Lowest;

GlobalRateMan.GateKeeperMonitor.Name = "GateKeeper";

GlobalRateMan.GateKeeperMonitor.IsBackground= true;

GlobalRateMan.GateKeeperMonitor.Start();

//change the text on the button to paused - webding font

GateKeeper.Text = ";";

GateKeeper.ToolTip =
RateManager.GlobalRateMan.GateKeeperMonitor.ThreadState.ToString();


//here is Analyze
Email(); //usual email code
System.Threading.Thread.Sleep(TimeSpan.FromMinutes(Double.Parse(GlobalRateMa
n.GateKeeperSleepTime))); //60 minutes

RateManager.GateKeeper.Subject = "GateKeeper is preparing to run Analysis
from Netapp-1";

[snip]

//work gets done here

//recursion controlled by sleeptime

Analyze();

When I examine the state of the thread thru the
GlobalRateMan.GateKeeperMonitor handle which is a static handle holding the
address of the thread,

it is stopped after about 2 hours. On another related note, I am noticing
other weird behavior like this thread will refuse to email if it is started
from the application_start event.
 
Question:
In writing a short demo, i've realized that this code is inherently flawed.
It will pop the stack (memory exhaustion) after a couple days of running
right because stack space isn't infinite?

Might there be a better way to do this.

method()
{
Sleep(5)
//work
method()
}
 
Hi,
<see inline>

Alvin Bruney said:
No, that's not the idea.
Main thread spawns child thread. Child thread calls method. Method sleeps,
wakes up does some work, calls itself (Method sleeps, wakes up does some
work, calls itself...)

why use recursion? because it easily accomplishes what i'm after with my
tite deadline.
The recursion looks like this
Method()
{
Thread.Sleep(60);
//do work
Method();
}

Well , that's what I'm saying, it's bad. Method cannot keep calling Method,
at a certain time, Method should stop calling Method. (e.g. recursion for
Fractorial)
The first Method call can't finish until the second did, and so
on....keeping all methods open until your thread finishes.

Recursion really doesn't help you _here_. It should be more easy with a
while loop.

HTH
greetings

Jhon said:
Hi,

I don't really know what's wrong with your code. But is there a specific
reason why you use recursion ?

Recursion:
An A=method n=invocation nr

A0 calls A
A1 calls A
A2 calls A
A3 doesn't call A
cleanup A3->A2->A1->A0

Since cleanup is delayed, it causes an overhead. And recursion can only
work well if at a certain point the function doesn't call itself anymore.

I would not use recursion in your case.

Do you have a try/catch inside Analyse ?

HTH
greetings




message news:[email protected]... letting
the
RateManager.GateKeeper("localhost",System.Configuration.ConfigurationSettings.AppSettings["toEmail"],System.Configuration.ConfigurationSettings.AppSetti
ngs["fromEmail"],"GateKeeper is initializing","GateKeeper Init");

//maintain a global handle so that i can examine thread behavior at runtime

GlobalRateMan.GateKeeperMonitor = new Thread (new ThreadStart
(RateManager.GateKeeper.Analyze));

GlobalRateMan.GateKeeperMonitor.Priority = ThreadPriority.Lowest;

GlobalRateMan.GateKeeperMonitor.Name = "GateKeeper";

GlobalRateMan.GateKeeperMonitor.IsBackground= true;

GlobalRateMan.GateKeeperMonitor.Start();

//change the text on the button to paused - webding font

GateKeeper.Text = ";";

GateKeeper.ToolTip =
RateManager.GlobalRateMan.GateKeeperMonitor.ThreadState.ToString();


//here is Analyze
Email(); //usual email code
System.Threading.Thread.Sleep(TimeSpan.FromMinutes(Double.Parse(GlobalRateMa
n.GateKeeperSleepTime))); //60 minutes

RateManager.GateKeeper.Subject = "GateKeeper is preparing to run Analysis
from Netapp-1";

[snip]

//work gets done here

//recursion controlled by sleeptime

Analyze();

When I examine the state of the thread thru the
GlobalRateMan.GateKeeperMonitor handle which is a static handle
holding
the
address of the thread,

it is stopped after about 2 hours. On another related note, I am noticing
other weird behavior like this thread will refuse to email if it is started
from the application_start event.
 
d'oh
A timer.

Don't know why i didn't think of this before(well i thought of it but i
thought it wouldn't work on the web).

I put a timer on there, and it is working, (not perfectly because it fires 3
events after the elapsed time and i only want one event) but that will
definitely work for now.

I played with the advanced properties a bit. This thing will actually let
you configure properties and then it will take the properties and persist it
in the webconfig file. All behind the scenes. talk about neat.

thanks

Alvin Bruney said:
Question:
In writing a short demo, i've realized that this code is inherently flawed.
It will pop the stack (memory exhaustion) after a couple days of running
right because stack space isn't infinite?

Might there be a better way to do this.

method()
{
Sleep(5)
//work
method()
}

letting
 
The stack is set to 1MB. Why not just code the loop:

while (true)
{
DoStuff(); //whatever you do every 60 minutes
sleep(SixtyMinutes);
}



Alvin Bruney said:
Question:
In writing a short demo, i've realized that this code is inherently flawed.
It will pop the stack (memory exhaustion) after a couple days of running
right because stack space isn't infinite?

Might there be a better way to do this.

method()
{
Sleep(5)
//work
method()
}

letting
 
Because the while construct is a very in-efficient wait state in terms of
cpu cycles.

Fred Mellender said:
The stack is set to 1MB. Why not just code the loop:

while (true)
{
DoStuff(); //whatever you do every 60 minutes
sleep(SixtyMinutes);
}
 
point taken. a while loop suffers from cpu burn cycle syndrome as well.
i've used a timer, it seems to be working. A timer actually waits on a
different thread so it doesn't consume near as much resources.

Jhon said:
Hi,
<see inline>

Alvin Bruney said:
No, that's not the idea.
Main thread spawns child thread. Child thread calls method. Method sleeps,
wakes up does some work, calls itself (Method sleeps, wakes up does some
work, calls itself...)

why use recursion? because it easily accomplishes what i'm after with my
tite deadline.
The recursion looks like this
Method()
{
Thread.Sleep(60);
//do work
Method();
}

Well , that's what I'm saying, it's bad. Method cannot keep calling Method,
at a certain time, Method should stop calling Method. (e.g. recursion for
Fractorial)
The first Method call can't finish until the second did, and so
on....keeping all methods open until your thread finishes.

Recursion really doesn't help you _here_. It should be more easy with a
while loop.

HTH
greetings

while.
Is 1
per run-time,
it
RateManager.GateKeeper("localhost",System.Configuration.ConfigurationSettings.AppSettings["toEmail"],System.Configuration.ConfigurationSettings.AppSetti
ngs["fromEmail"],"GateKeeper is initializing","GateKeeper Init");

//maintain a global handle so that i can examine thread behavior at
runtime

GlobalRateMan.GateKeeperMonitor = new Thread (new ThreadStart
(RateManager.GateKeeper.Analyze));

GlobalRateMan.GateKeeperMonitor.Priority = ThreadPriority.Lowest;

GlobalRateMan.GateKeeperMonitor.Name = "GateKeeper";

GlobalRateMan.GateKeeperMonitor.IsBackground= true;

GlobalRateMan.GateKeeperMonitor.Start();

//change the text on the button to paused - webding font

GateKeeper.Text = ";";

GateKeeper.ToolTip =
RateManager.GlobalRateMan.GateKeeperMonitor.ThreadState.ToString();


//here is Analyze
Email(); //usual email code
System.Threading.Thread.Sleep(TimeSpan.FromMinutes(Double.Parse(GlobalRateMa
n.GateKeeperSleepTime))); //60 minutes

RateManager.GateKeeper.Subject = "GateKeeper is preparing to run Analysis
from Netapp-1";

[snip]

//work gets done here

//recursion controlled by sleeptime

Analyze();

When I examine the state of the thread thru the
GlobalRateMan.GateKeeperMonitor handle which is a static handle holding
the
address of the thread,

it is stopped after about 2 hours. On another related note, I am noticing
other weird behavior like this thread will refuse to email if it is
started
from the application_start event.
 
hi,
"Alvin Bruney" <vapordan_spam_me_not@hotmail_no_spamhotmail.com> wrote in
message news:[email protected]...
point taken. a while loop suffers from cpu burn cycle syndrome as well.
i've used a timer, it seems to be working. A timer actually waits on a
different thread so it doesn't consume near as much resources.

Polling in a while loop is bad for cpu cycles, something like:
while ( form.Blabla != "klkk" ) { /*just wait, do nothing*/ };

But you aren't doing that, each loop you sleep an hour and sleeping doesn't
cause cpu cycles, you should see it in the right context.

Nevertheless using a Timer is a good way too.

HTH
greetings
 
Alvin Bruney said:
Because the while construct is a very in-efficient wait state in terms of
cpu cycles.

Not with the "sleep(SixtyMinutes)" bit in there. Fred wasn't suggesting
a tight loop.
 
Alvin Bruney said:
point taken. a while loop suffers from cpu burn cycle syndrome as well.
i've used a timer, it seems to be working. A timer actually waits on a
different thread so it doesn't consume near as much resources.

What makes you think that a while loop with a sleep in would consume
lots of resources?
 
well for one, the loop construct has to be loaded to execute, but then it
does nothing because the main thread is sleeping so it gets removed from cpu
queue, only to be reloaded again after the timer event fires. That is a burn
cycle because the cpu load resulted in no real work being done.

can you tell i'm grasping?
 
i thought about this code i put out and i feel i must apologize for this
terrible code. jeez talk about a poor idea in production...

Alvin Bruney said:
I'm observing that a sleeping thread changes to stopped after a while. Is
that accepted framework behavior for web applications?

My thread basically does some work, and sleeps for 60 minutes before calling
itself recursively, which means it is supposed to run on the hour every
hour. But it automatically stops after 2 hours. I only get 2 emails, 1 per
hour and then nothing. When I examine the threadstate during run-time, it
has changed from background, waitsleepjoin to stopped. I'm just letting the
app sit there so I know nothing else is going on in the background. Here's
the code.

//I manually start the thread when the application launches
RateManager.GateKeeper worker = new
RateManager.GateKeeper("localhost",System.Configuration.ConfigurationSettings.AppSettings["toEmail"],System.Configuration.ConfigurationSettings.AppSetti
ngs["fromEmail"],"GateKeeper is initializing","GateKeeper Init");

//maintain a global handle so that i can examine thread behavior at runtime

GlobalRateMan.GateKeeperMonitor = new Thread (new ThreadStart
(RateManager.GateKeeper.Analyze));

GlobalRateMan.GateKeeperMonitor.Priority = ThreadPriority.Lowest;

GlobalRateMan.GateKeeperMonitor.Name = "GateKeeper";

GlobalRateMan.GateKeeperMonitor.IsBackground= true;

GlobalRateMan.GateKeeperMonitor.Start();

//change the text on the button to paused - webding font

GateKeeper.Text = ";";

GateKeeper.ToolTip =
RateManager.GlobalRateMan.GateKeeperMonitor.ThreadState.ToString();


//here is Analyze
Email(); //usual email code

System.Threading.Thread.Sleep(TimeSpan.FromMinutes(Double.Parse(GlobalRateMa
n.GateKeeperSleepTime))); //60 minutes

RateManager.GateKeeper.Subject = "GateKeeper is preparing to run Analysis
from Netapp-1";

[snip]

//work gets done here

//recursion controlled by sleeptime

Analyze();

When I examine the state of the thread thru the
GlobalRateMan.GateKeeperMonitor handle which is a static handle holding the
address of the thread,

it is stopped after about 2 hours. On another related note, I am noticing
other weird behavior like this thread will refuse to email if it is started
from the application_start event.
 
Alvin Bruney said:
well for one, the loop construct has to be loaded to execute, but then it
does nothing because the main thread is sleeping so it gets removed from cpu
queue, only to be reloaded again after the timer event fires. That is a burn
cycle because the cpu load resulted in no real work being done.

can you tell i'm grasping?

Yup :)
 
Back
Top