Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / New Users / November 2006

Tip: Looking for answers? Try searching our database.

How do I Sleep for a specified amount of time and relinquish contr

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
nickdu - 16 Nov 2006 15:07 GMT
In the docs for Thread.Sleep() it appears unless I specify 0 my thread will
still use the rest of its quanta (I guess doing nothing useful) as opposed to
being suspended right away to allow other runable thread to execute.

What's the best way to sleep for a specified amount of time and relinquish
control right away as opposed to using up the rest of my quanta?  Do I need
to call the Win32 Sleep()?  Do I need to call WaitOne() on a synchronization
object?
Signature

Thanks,
Nick

nicknospamdu@community.nospam
remove "nospam" change community. to msn.com

Michael Nemtsev - 16 Nov 2006 18:35 GMT
Hello nickdu,

Use TimeSpan as param of the Thread.Sleep method
For example Thread.Sleep (TimeSpan.FromSeconds (30)); //sleep for 30 secs

for example
n> In the docs for Thread.Sleep() it appears unless I specify 0 my
n> thread will still use the rest of its quanta (I guess doing nothing
n> useful) as opposed to being suspended right away to allow other
n> runable thread to execute.
n>
n> What's the best way to sleep for a specified amount of time and
n> relinquish control right away as opposed to using up the rest of my
n> quanta?  Do I need to call the Win32 Sleep()?  Do I need to call
n> WaitOne() on a synchronization object?
n>
n> nicknospamdu@community.nospam
n> remove "nospam" change community. to msn.com
---
WBR,
Michael  Nemtsev [C# MVP] :: blog: http://spaces.live.com/laflour

"At times one remains faithful to a cause only because its opponents do not
cease to be insipid." (c) Friedrich Nietzsche
nickdu - 16 Nov 2006 19:16 GMT
That's what I was doing which didn't appear to be working based on my
observations.  Yes, the thread that executed Sleep(<30 second timespan>) was
stopped from doing anything useful for 30 seconds, but it also appeared to be
consuming the rest of the thread's quanta.  What I did instead, which appears
to do what I want is:

wait = new AutoResetEvent(false);
while (true)
   {
   // do some work
   ...
   wait.WaitOne(thinkTime, true);
   }

So I wait on an event that will never be signaled and I specify as a timeout
the amount of time I want to sleep.  Based on my observations I don't have
the odd behavior I was seeing before which seems to be explained by the
thread continuing to use its quanta when sleeping.

I'm guessing calling the Windows Sleep() API via pinvoke would also solve my
problem, but that's just a guess.
Signature

Thanks,
Nick

nicknospamdu@community.nospam
remove "nospam" change community. to msn.com

> Hello nickdu,
>
[quoted text clipped - 20 lines]
> "At times one remains faithful to a cause only because its opponents do not
> cease to be insipid." (c) Friedrich Nietzsche
Michael Nemtsev - 16 Nov 2006 20:41 GMT
Hello nickdu,

n> That's what I was doing which didn't appear to be working based on my
n> observations.  Yes, the thread that executed Sleep(<30 second
n> timespan>) was stopped from doing anything useful for 30 seconds, but
n> it also appeared to be consuming the rest of the thread's quanta.

Don't u mix this with SpinWait method?
When u waits or sleep a thread relinquish its allocation of CPU time and
WaitSleepJoin is set to the ThreadState property

---
WBR,
Michael  Nemtsev [C# MVP] :: blog: http://spaces.live.com/laflour

"At times one remains faithful to a cause only because its opponents do not
cease to be insipid." (c) Friedrich Nietzsche
nickdu - 16 Nov 2006 21:54 GMT
No, I'm not mixing Sleep() with SpinWait().  I believe Sleep(), as
implemented by the .NET framework, is not relinquishing control to runnable
threads.  And it even mentions this in the docs.  It say something to the
effect of "specify 0 to relinquish control to runnable threads".  And based
on my observations it appears to be behaving that way, not relinquishing
control as soon as I call Sleep().  It appears to be finishing using its
quanta.  And based on the fact that the behavior improved to what I was
looking to achieve when I changed it to a WaitOne(), I would say that Sleep()
with a non zero value is not really doing what I want, and maybe not doing
what many others are thinking it should do.
Signature

Thanks,
Nick

nicknospamdu@community.nospam
remove "nospam" change community. to msn.com

> Hello nickdu,
>
[quoted text clipped - 13 lines]
> "At times one remains faithful to a cause only because its opponents do not
> cease to be insipid." (c) Friedrich Nietzsche
Chris Mullins - 16 Nov 2006 22:00 GMT
Sleep(0) and Sleep(1) do have a few minor differences between then, aside
from the obvious.

The key is that Sleep(0) won't allow any lower priority threads to be
scheduled, whereas Sleep(1) will.

Lots of good detail by Joe Duffy at:
http://www.bluebytesoftware.com/blog/PermaLink,guid,1c013d42-c983-4102-9233-ca54
b8f3d1a1.aspx


--
Chris Mullins, MCSD.NET, MCPD:Enterprise
http://www.coversant.net/blogs/cmullins

> No, I'm not mixing Sleep() with SpinWait().  I believe Sleep(), as
> implemented by the .NET framework, is not relinquishing control to
[quoted text clipped - 28 lines]
>> not
>> cease to be insipid." (c) Friedrich Nietzsche
Peter Duniho - 16 Nov 2006 22:05 GMT
> No, I'm not mixing Sleep() with SpinWait().  I believe Sleep(), as
> implemented by the .NET framework, is not relinquishing control to
> runnable
> threads.

Sleep() as implemented by the .NET Framework had better just be calling the
Windows API function Sleep().  And that does indeed cause the calling thread
to immediately be suspended, with the next runnable thread being scheduled
for the CPU.

>  And it even mentions this in the docs.  It say something to the
> effect of "specify 0 to relinquish control to runnable threads".

That's right.  If you don't want to sleep for any specific amount of time,
but still want to give up your timeslice to other runnable threads, you call
Sleep() with the parameter of 0.

That doesn't mean that calling it with some other value doesn't also
relinquish the CPU.  It just means that if *all* you want to do is
relinquish the CPU, you can use the value of 0.

> And based
> on my observations it appears to be behaving that way, not relinquishing
> control as soon as I call Sleep().  It appears to be finishing using its
> quanta.

Define "my observations".  What makes you believe that after calling
Sleep(), your thread continues to run out its timeslice?

> And based on the fact that the behavior improved to what I was
> looking to achieve when I changed it to a WaitOne(), I would say that
> Sleep()
> with a non zero value is not really doing what I want, and maybe not doing
> what many others are thinking it should do.

You haven't described your observations, so how do you justify your claim
that calling WaitOne() with a timeout "behaves better" than simply calling
Sleep() with the same timeout?

Pete
Chris Mullins - 17 Nov 2006 00:48 GMT
> Sleep() as implemented by the .NET Framework had better just be calling
> the Windows API function Sleep().  And that does indeed cause the calling
> thread to immediately be suspended, with the next runnable thread being
> scheduled for the CPU.

Well, it's not that simple. (It never is, is it?)

On hyperthreaded processors, the behavior is slighly different. Jeff Richter
goes into this a tiny bit at:
http://msdn.microsoft.com/msdnmag/issues/05/10/ConcurrentAffairs/
http://msdn.microsoft.com/msdnmag/issues/05/10/ConcurrentAffairs/default.aspx?lo
c=&side=true#a


If I understood the issues here better, I would explain them. I'm hoping
someone much smarter than me fills in all the issues here.

> That doesn't mean that calling it with some other value doesn't also
> relinquish the CPU.  It just means that if *all* you want to do is
> relinquish the CPU, you can use the value of 0.

There are some good reasons no to use "0" as the value passed to sleep. Joe
Duffy goes into the details at:
http://www.bluebytesoftware.com/blog/PermaLink,guid,1c013d42-c983-4102-9233-ca54
b8f3d1a1.aspx


> What makes you believe that after calling Sleep(), your thread continues
> to run out its timeslice?

Ya know, if I had to figure that out, and had full access to the machine
with all the hardcores debuggers I could find, it would stil be VERY hard to
figure out. I would be (pleasently) shocked to see an easy way to determine
this.

--
Chris Mullins, MCSD.NET, MCPD:Enterprise
http://www.coversant.net/blogs/cmullins
Peter Duniho - 17 Nov 2006 07:40 GMT
> [...]
>> That doesn't mean that calling it with some other value doesn't also
>> relinquish the CPU.  It just means that if *all* you want to do is
>> relinquish the CPU, you can use the value of 0.
>
> There are some good reasons no to use "0" as the value passed to sleep.

This is true, depending on what your goals are.  I did not intend my reply
to be a fully detailed treatise on the exact behavior of Sleep().  However,
the OP is claiming that even when he calls Sleep() with a *non-zero* value,
the thread continues to run until the timeslice is finished.

I hope we can agree that this is a *highly* unlikely scenario.

Pete
Kevin Spencer - 17 Nov 2006 12:00 GMT
I take Sonata every night, just before bedtime, since once I get to sleep, I
generally stay asleep. However, under stress, I occasionally add Lorazepam
to the mix.

Signature

;-),

Kevin Spencer
Microsoft MVP
Ministry of Software Development
http://unclechutney.blogspot.com

Any experience you can walk away from
is a good one.

>> [...]
>>> That doesn't mean that calling it with some other value doesn't also
[quoted text clipped - 12 lines]
>
> Pete
nickdu - 17 Nov 2006 03:08 GMT
From reading the docs I'm remember it saying something about continuing to
use the thread's quanta.  I don't think the .NET Thread.Sleep() simply calls
the Win32 Sleep() API.

You're correct that I didn't go into specifics on my observations which I
will do now.  I started looking into this because a load simulator I wrote to
simulate a bunch of clients against our SQL database was exhibiting some
weird behavior.  I noticed that about every 20 seconds or so the output of my
routine would pause for about 10 seconds.  By the way, this was run on an 8
way machine and I started 100 threads each opening a connection to the
database and executing queries with a 30 second think time.  The think time I
simulated with a Sleep() call.  So I first figured that SQL might be having
some problems which was causing my delay.  I ran a SQL profile session and
all the numbers looked pretty good, in the 10 to 20 ms range.  So then I
figured it was my client program.  After reading the part about Sleep()
continuing to use the thread's quanta I decided to use a wait function to see
if that would produce any better results.  And indeed it did.  I no longer
see the delay in my output.
Signature

Thanks,
Nick

nicknospamdu@community.nospam
remove "nospam" change community. to msn.com

> > No, I'm not mixing Sleep() with SpinWait().  I believe Sleep(), as
> > implemented by the .NET framework, is not relinquishing control to
[quoted text clipped - 36 lines]
>
> Pete
Peter Duniho - 17 Nov 2006 07:48 GMT
> From reading the docs I'm remember it saying something about continuing to
> use the thread's quanta.

From reading which docs?  It just makes no sense that any version of Sleep()
would in fact do a spin wait until the timeslice is up.  The moment you call
Sleep() (.NET or Windows API) with a non-zero value, that thread should be
suspended (and most of the time even with zero passed to it).  I have a hard
time believing you've seen any official documentation that says otherwise.

The fact that using the wait-on-an-event method instead changes the behavior
doesn't prove that Sleep() was using up the timeslice.  It just means it
does something different that changed the behavior.

Pete
nickdu - 17 Nov 2006 13:35 GMT
I tried to go back and find the docs I'm referring to but can't.  So the only
conclusion I can come to is that I somehow read that into the docs based on
seeing the part about specifying zero to relinquish control to other waiting
threads.

Though I don't think this caused me to see something in the behavior of my
program after making the change that really isn't there.  I no longer see
this considerable lag in my output (which I'm doing via a
Console.WriteLine()).  Maybe that's explained by  Jeffrey's post where he
mentions that the OS will boost the priority of a thread after a Wait().
Signature

Thanks,
Nick

nicknospamdu@community.nospam
remove "nospam" change community. to msn.com

> > From reading the docs I'm remember it saying something about continuing to
> > use the thread's quanta.
[quoted text clipped - 10 lines]
>
> Pete
Peter Duniho - 17 Nov 2006 17:55 GMT
> [...] I no longer see
> this considerable lag in my output (which I'm doing via a
> Console.WriteLine()).  Maybe that's explained by  Jeffrey's post where he
> mentions that the OS will boost the priority of a thread after a Wait().

Could be.  Since you still have failed to provide any actual code or
detailed description of what is actually happening, it's very hard for
anyone else to say.

All I'm saying is that I'm practically certain that when you call Sleep()
with a non-zero value, your thread does not continue running.

Pete
nickdu - 22 Nov 2006 19:40 GMT
Here is the code in question.

        try
            {
            portfolios = eom.Portfolios[Eom.Side.Client];
            foreach(Eom.IPortfolio port in portfolios)
                {
                list.Add(port.Name);
                }
            names = (string[]) list.ToArray(typeof(string));
           
            while (true)
                {
//                Thread.Sleep(this._thinkTime);
                wait.WaitOne(this._thinkTime, true);
                name = names[rand.Next(0, names.Length)];
                portfolio = (Eom.IClientPortfolio) portfolios[name];

                orders = portfolio.Orders;
                if (orders != null)
                    {
                    foreach(Eom.IOrder orer in orders)
                        {
                        }
                    }

                marketPortfolios = portfolio.MarketPortfolios;

                foreach (Eom.IProperty prop in portfolio.Properties)
                    {
                    }

                // Set some properties

                // Set client portfolio property at client portfolio.

                property = portfolio.Properties[Eom.Properties.TradingInstructions];

                if (property != null)
                    property.Value = "Nick's trading instructions.";
                else
                    portfolio.Properties.Add(Eom.Properties.TradingInstructions, "Nick's
trading instructions.");

                // Set client order property at client portfolio.

                property = portfolio.Properties[Eom.Properties.Guaranteed];
                if (property != null)
                    property.Value = true;
                else
                    portfolio.Properties.Add(Eom.Properties.Guaranteed, true);

                // Set client order property at client order.

                }
            }
        catch(Exception e)
            {
            Console.WriteLine("Worker encountered the following exception:\n\n{0}",
e.ToString());
            throw;
            }

Signature

Thanks,
Nick

nicknospamdu@community.nospam
remove "nospam" change community. to msn.com

Jeffrey Tan[MSFT] - 24 Nov 2006 09:44 GMT
Hi Nick,

Thanks for your feedback.

Most part of the code snippet you provided is the business code of your
application which is not informative regarding the Sleep/Event.WaitOne
delay. It is hard for us to provide any further information based on this
code snippet. Thanks for your understanding.

Can you provide more information regarding the "output rountine" in your
application and thread modeling in your application? Also, what is the
"better result" behavior as you described?

Thanks.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
Jeffrey Tan[MSFT] - 17 Nov 2006 08:02 GMT
Hi Nick,

It costs me some time to read all your discussions with the community
before I can provide a reply to you.

I am not sure if I understand you completely. Based on my understanding,
you are writting a stress simulator application for SQL Server. After
openning a connection to the SQL Server, the thread uses Thread.Sleep()
method to simulate 30 second *processing time*(think time). However, every
20 seconds or so the output of your routine would pause for about 10
seconds, so you wanted to find out the root cause of this problem. If I
have misunderstood you, please feel free to tell me, thanks.

The point that I do not understand well is what "output of your routine
pause for 10 seconds" means. Can you tell me what is this "routine"? How
does the routine generate output?

Another point:
>Sleep() continuing to use the thread's quanta I decided to use a wait
function to see
>if that would produce any better results
I think I do not understand your expected behavior completely. Can you
telll me what is the "better result" behavior? Then I will judge to see why
Thread.Sleep() does not meet your need. Thanks.

Anyway, I wanted to share some information with you:

1. .Net2.0 System.Threading.Thread.Sleep() method internally calls Win32
SleepEx() API. I can prove this by setting a breakpoint in Kernel32!SleepEx
API in windbg for a .Net2.0 Winform application. Below is the call stack I
got while I call Thread.Sleep() method in .Net:

0:000> !dumpstack
Current frame: KERNEL32!SleepEx
ChildEBP RetAddr  Caller,Callee
0013f230 792144fc mscorwks!Thread::UserSleep+0x93, calling KERNEL32!SleepEx
0013f250 79214574 mscorwks!ThreadNative::Sleep+0x30, calling
mscorwks!Thread::UserSleep
0013f260 011a03a6 011a03a6
0013f28c 79bbaeb0  (stub for System.Threading.Thread.Sleep), calling
011a037c
0013f290 0111026f (MethodDesc 0xc253c8 +0x17
winformtest.Form1.button1_Click), calling 79bbaeab (MethodDesc 0x79bbaeb0
System.Threading.Thread.Sleep)
0013f2a0 7b881fa4 (MethodDesc 0x7b9e5108 +0x54
System.Windows.Forms.Control.OnClick)

If you want to know more detailed information, you may download SSCLI2.0
project to view the sample source code of ThreadNative::Sleep,
Thread::UserSleep of CLR.  
"Shared Source Common Language Infrastructure 2.0 Release"
http://www.microsoft.com/downloads/details.aspx?FamilyId=8C09FD61-3F26-4555-
AE17-3121B4F51D4D&displaylang=en

2. In Windows thread schedulling, any wait operation will be decreased 1
point of quantum unit. And the default thread quantum has about 3 quantum
units to run. So after Sleep(30000) calling, the calling thread will go
into wait state for 30 seconds, then its quantum will reduce 1 unit. Note:
once in wait state, this thread can not be scheduled for execution, other
thread will execute. Also, after wakeup, the calling thread will not run
immediately, it will be placed in the read thread queue for scheduling.

For event/semaphore, it will normally behaves the same as Thread.Sleep().
However, after wakeup, Windows will provide a special priority boost to the
calling thread, so that the wakeup thread can run immediately. I am not
sure if this difference is the root cause of your problem.

3. If you think your simulator application is hanging for 10 seconds, the
best technology to troubshoot is using "Process Explorer" to examine what
each thread is hanging about. You may just examine each thread call stack
during this 10 seconds hang. The call stack will reveal what's going on.
The following article may not be very relevant to your question, but it
demonstrates how to troubleshoot the hang/delay style problem:
http://www.codeproject.com/system/NoDeleteDelay.asp

Finally, the Windows thread scheduling is not a trivial topic, it is
covered best in Chapter 6 of Mark E. Russinovich's wonderful book <Windows
Internals>. More specificly, "Thread Scheduling" section is dedicated for
this topic. You may give it a reading to understand more background
information.

Hope this helps.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.