Home All Groups Group Topic Archive Search About

Sleep function in vb.net

Author
2 Jun 2009 10:21 PM
John
Hi

Is there a sleep function in vb.net which when used gives time to other apps
to maintain responsiveness of other apps which this app is on sleep?

Thanks

Regards

Author
2 Jun 2009 11:09 PM
Herfried K. Wagner [MVP]
"John" <info@nospam.infovis.co.uk> schrieb:
> Is there a sleep function in vb.net which when used gives time to other
> apps to maintain responsiveness of other apps which this app is on sleep?

Take a look at 'Thread.Sleep'.

--
M S   Herfried K. Wagner
M V P  <URL:http://dotnet.mvps.org/>
V B   <URL:http://dotnet.mvps.org/dotnet/faqs/>
Author
3 Jun 2009 12:04 AM
Mike
John wrote:
> Hi
>
> Is there a sleep function in vb.net which when used gives time to other apps
> to maintain responsiveness of other apps which this app is on sleep?

    System.Threading.Thread.Sleep(Milliseconds).

or

    Imports System.Threading.Thread
    ....
    ....
    Sleep(milliseconds)

However, I'm curious about your usage.  This is a deep subject but I
will try to summarize.  I apologize for the length of this message,
but this is one of my favorite topics.  :-)

Windows is a pre-emptive OS and all processes/threads will get a
quantum as time to do work.  All things being equal (thread priority,
no waitable kernel objects), the OS thread scheduler will delegate
"equal" time (called a QUANTUM) to all equal priority threads.

A quantum is around 10-15 msecs depending on the CPU. 15ms is pretty
average with today dual-core machines and all Windows are NT based
(old 95 had a 10-13ms quantum).  It is called quantum because its a
multiple of the minimum sleep. Assuming 15ms is the quantum for your
machine:

  Sleep(1) to Sleep(15) will always sleep 15 ms.
  Sleep(16) will sleep two quantums or 30 ms
  Sleep(31) will sleep 3 quantums or 45 ms

and so on. 1 quantum = 15 ms

However,

  Sleep(0)

is a special sleep which acts more like a POKE or YIELD (in RTOS
terms) to wake others threads in the systems, but Windows will not
wait one quantum to rewake up the calling thread and restart it. So
this can be a problem if using Sleep(0) the wrong way. I will explain why.

If you think your process is "hogging" the system, the reasons are
generally:

   - If the process is a GUI applet, it may not be processing the
     message queue fast enough.  However, this generally slows your
     process down, not others. Calling My.Application.DoEvents() will
     solve that problem.

   - The typical main reason is the process/thread context switching is
     too high.

Context switching (CS) is a very expensive Windows and CPU operation.
A CS is when the WINDOWS:

   - Stops the current thread X in the CPU (preemption),
   - Swaps out all its code, stacks and memory usage, stores it,
   - Swaps in the Next thread Y code, stack, memory usage from storage,
   - Starts the thread Y

This is done, again when all things are equal, every QUANTUM for all
threads.

So a process thread will HOG the CPU when  its CS is too high - PERIOD
Lower the CS, and the machine will begin to run smoothly.

You can see the context switching count in the task manager for any
process.  For individual threads, use Performance Counter.

Lets use this example.

Lets suppose you have a LOOP that does a lot of work for you, reading
and processes data blocks:

    Sub DoWork1()
      while I.Have.Data do
         work_on_data
       end while
    end sub

You realize this:

    "Wow! DoWork() is necessary, but its really dragging the
     system down. The CPU is high and other processes are
     not responsive. Need to improve."

The classic natural approach is to do what you asked, put in some
sleep time slicing:

    Sub DoWork1(ms as integer)
      while I.Have.Data do
         work_on_data
         Sleep(ms)
       end while
    end sub

Now, without the slice, again Windows will automatically preempt by
doing a context switch somewhere in the above code and will do so at
the spot where the compiled lines translated OP CODES clock cycles add
up to a quantum - this is called a natural time slice.

By adding the Sleep() slice, you begin to altering the natural time
slicing.

So what value do you use?

If ms = 0, this MAY BE a mistake because it will increase the context
switching.  The CPU usage might be higher than without it.

You can use 1 quantum (1 to 15) or more, this is where you will begin
to be friendly but without a doubt the DoWork1() will take even
longer.  You will be friendly with the system but the time to
completion may be beyond an acceptable level.

So this is a fine tuning process. There are various fine tuning
methods. Remember the idea is to reduce the expensive Context
Switching overhead. One idea is to only do so every N number of records:

    Sub DoWork1(slicer as integer)
      dim x as integer = slicer
      while I.Have.Data do
         work_on_data
         if Slicer > 0 AndElse x = 0 then
            Sleep(1)
            x = Slicer ' start counter again
            continue while
         end if
         x = x - 1
       end while
    end sub

But again, its a fine tunning process how many records are processed
before you sleep.  Sometimes, this will afford you to do POKE,
Sleep(0), if you only do it occasionally, not all the time.

Also, sometimes you can have hardware interrupt based context
switching depending on what you doing in the loop. Reading and writing
to DISK or anything that have hardware Interrupts, including moving
the mouse around, that will force a pre-emptive context switching
to process the interrupt.

Kernel Objects and Event Drive Processes

Whenever possible, the ideal solution is to use EVENTS or Kernel
Objects.  This is ideal because the Windows Scheduler will put the
thread to sleep and will only wake it up only when the event is
signal.  This is one of the exceptions to the "All things being equal"
rule.  A thread waiting on an event is optimal - performance wise.

But depending on what you doing, using events are not always possible,
but to illustrate it using the above example, suppose you are doing
polling, waiting for data so you can process it.

If you create a timer to poll for data, if its frequency is too high,
it can wasteful and if its processes data far too often, that can bog
down the machine as well.

If you had a way to get a SIGNAL when the data arrives, that would be
ideal and this is often what to look for to improve performance and
cooperation with other processes running.

But even then, if you did have a SIGNAL, you might not want to process
the data right away.  Your design can wait until you get X amount or
threshold of data before you process. So the signal might start a
timer to built up the data queue and only process when  X is reached
or the timer expires.  In our works, this is common technique to
improve performance and queue processing.

Of course, this is all implementation specific so it all depends on
what you doing, but in general if you want to be cooperative with
other processes and are asking about Sleep(), consider the concepts I
touch upon above because a Sleep is not always the solution. The
overall solution to look for, is to reduce the context switching
without negatively slowing down your work.

--
Author
3 Jun 2009 6:16 AM
Cor Ligthert[MVP]
Mike,

Thanks, your message contains elements I always wanted to know but did not
know.

Cor




Show quoteHide quote
"Mike" <unkn***@unknown.tv> wrote in message
news:uYz$V794JHA.1420@TK2MSFTNGP04.phx.gbl...
> John wrote:
>> Hi
>>
>> Is there a sleep function in vb.net which when used gives time to other
>> apps to maintain responsiveness of other apps which this app is on sleep?
>
>    System.Threading.Thread.Sleep(Milliseconds).
>
> or
>
>    Imports System.Threading.Thread
>    ....
>    ....
>    Sleep(milliseconds)
>
> However, I'm curious about your usage.  This is a deep subject but I will
> try to summarize.  I apologize for the length of this message, but this is
> one of my favorite topics.  :-)
>
> Windows is a pre-emptive OS and all processes/threads will get a quantum
> as time to do work.  All things being equal (thread priority, no waitable
> kernel objects), the OS thread scheduler will delegate "equal" time
> (called a QUANTUM) to all equal priority threads.
>
> A quantum is around 10-15 msecs depending on the CPU. 15ms is pretty
> average with today dual-core machines and all Windows are NT based (old 95
> had a 10-13ms quantum).  It is called quantum because its a multiple of
> the minimum sleep. Assuming 15ms is the quantum for your machine:
>
>  Sleep(1) to Sleep(15) will always sleep 15 ms.
>  Sleep(16) will sleep two quantums or 30 ms
>  Sleep(31) will sleep 3 quantums or 45 ms
>
> and so on. 1 quantum = 15 ms
>
> However,
>
>  Sleep(0)
>
> is a special sleep which acts more like a POKE or YIELD (in RTOS terms) to
> wake others threads in the systems, but Windows will not wait one quantum
> to rewake up the calling thread and restart it. So this can be a problem
> if using Sleep(0) the wrong way. I will explain why.
>
> If you think your process is "hogging" the system, the reasons are
> generally:
>
>   - If the process is a GUI applet, it may not be processing the
>     message queue fast enough.  However, this generally slows your
>     process down, not others. Calling My.Application.DoEvents() will
>     solve that problem.
>
>   - The typical main reason is the process/thread context switching is
>     too high.
>
> Context switching (CS) is a very expensive Windows and CPU operation. A CS
> is when the WINDOWS:
>
>   - Stops the current thread X in the CPU (preemption),
>   - Swaps out all its code, stacks and memory usage, stores it,
>   - Swaps in the Next thread Y code, stack, memory usage from storage,
>   - Starts the thread Y
>
> This is done, again when all things are equal, every QUANTUM for all
> threads.
>
> So a process thread will HOG the CPU when  its CS is too high - PERIOD
> Lower the CS, and the machine will begin to run smoothly.
>
> You can see the context switching count in the task manager for any
> process.  For individual threads, use Performance Counter.
>
> Lets use this example.
>
> Lets suppose you have a LOOP that does a lot of work for you, reading and
> processes data blocks:
>
>    Sub DoWork1()
>      while I.Have.Data do
>         work_on_data
>       end while
>    end sub
>
> You realize this:
>
>    "Wow! DoWork() is necessary, but its really dragging the
>     system down. The CPU is high and other processes are
>     not responsive. Need to improve."
>
> The classic natural approach is to do what you asked, put in some sleep
> time slicing:
>
>    Sub DoWork1(ms as integer)
>      while I.Have.Data do
>         work_on_data
>         Sleep(ms)
>       end while
>    end sub
>
> Now, without the slice, again Windows will automatically preempt by doing
> a context switch somewhere in the above code and will do so at the spot
> where the compiled lines translated OP CODES clock cycles add up to a
> quantum - this is called a natural time slice.
>
> By adding the Sleep() slice, you begin to altering the natural time
> slicing.
>
> So what value do you use?
>
> If ms = 0, this MAY BE a mistake because it will increase the context
> switching.  The CPU usage might be higher than without it.
>
> You can use 1 quantum (1 to 15) or more, this is where you will begin to
> be friendly but without a doubt the DoWork1() will take even longer.  You
> will be friendly with the system but the time to completion may be beyond
> an acceptable level.
>
> So this is a fine tuning process. There are various fine tuning methods.
> Remember the idea is to reduce the expensive Context Switching overhead.
> One idea is to only do so every N number of records:
>
>    Sub DoWork1(slicer as integer)
>      dim x as integer = slicer
>      while I.Have.Data do
>         work_on_data
>         if Slicer > 0 AndElse x = 0 then
>            Sleep(1)
>            x = Slicer ' start counter again
>            continue while
>         end if
>         x = x - 1
>       end while
>    end sub
>
> But again, its a fine tunning process how many records are processed
> before you sleep.  Sometimes, this will afford you to do POKE, Sleep(0),
> if you only do it occasionally, not all the time.
>
> Also, sometimes you can have hardware interrupt based context switching
> depending on what you doing in the loop. Reading and writing to DISK or
> anything that have hardware Interrupts, including moving the mouse around,
> that will force a pre-emptive context switching
> to process the interrupt.
>
> Kernel Objects and Event Drive Processes
>
> Whenever possible, the ideal solution is to use EVENTS or Kernel Objects.
> This is ideal because the Windows Scheduler will put the thread to sleep
> and will only wake it up only when the event is signal.  This is one of
> the exceptions to the "All things being equal" rule.  A thread waiting on
> an event is optimal - performance wise.
>
> But depending on what you doing, using events are not always possible, but
> to illustrate it using the above example, suppose you are doing polling,
> waiting for data so you can process it.
>
> If you create a timer to poll for data, if its frequency is too high, it
> can wasteful and if its processes data far too often, that can bog down
> the machine as well.
>
> If you had a way to get a SIGNAL when the data arrives, that would be
> ideal and this is often what to look for to improve performance and
> cooperation with other processes running.
>
> But even then, if you did have a SIGNAL, you might not want to process the
> data right away.  Your design can wait until you get X amount or threshold
> of data before you process. So the signal might start a timer to built up
> the data queue and only process when  X is reached or the timer expires.
> In our works, this is common technique to improve performance and queue
> processing.
>
> Of course, this is all implementation specific so it all depends on what
> you doing, but in general if you want to be cooperative with other
> processes and are asking about Sleep(), consider the concepts I touch upon
> above because a Sleep is not always the solution. The overall solution to
> look for, is to reduce the context switching without negatively slowing
> down your work.
>
> --
Author
3 Jun 2009 2:42 PM
eBob.com
"Mike" <unkn***@unknown.tv> wrote in message
news:uYz$V794JHA.1420@TK2MSFTNGP04.phx.gbl...
> <significant snip>

> Context switching (CS) is a very expensive Windows and CPU operation. A CS
> is when the WINDOWS:
>
>   - Stops the current thread X in the CPU (preemption),
>   - Swaps out all its code, stacks and memory usage, stores it,
>   - Swaps in the Next thread Y code, stack, memory usage from storage,
>   - Starts the thread Y
>
Surely (meaning I sure hope) the swap out/in only happens if there is not
enough RAM to accomodate the working sets of both threads.  So if X and Y
are the only two active threads, and there is enough RAM to hold both
working sets, then there would be no swapping.  Right?  Or did I waste my
money putting a lot of RAM into my new system?

Also, does swapping happen on a thread basis or process basis?  It seems to
me that it would have to be on a process basis because different threads in
the same process might be using the same memory.

Thanks,  Bob
Author
3 Jun 2009 8:52 PM
Nobody
Show quote Hide quote
"eBob.com" <faken***@totallybogus.com> wrote in message
news:%23mcPKmF5JHA.4116@TK2MSFTNGP04.phx.gbl...
>
> "Mike" <unkn***@unknown.tv> wrote in message
> news:uYz$V794JHA.1420@TK2MSFTNGP04.phx.gbl...
>> <significant snip>
>
>> Context switching (CS) is a very expensive Windows and CPU operation. A
>> CS is when the WINDOWS:
>>
>>   - Stops the current thread X in the CPU (preemption),
>>   - Swaps out all its code, stacks and memory usage, stores it,
>>   - Swaps in the Next thread Y code, stack, memory usage from storage,
>>   - Starts the thread Y
>>
> Surely (meaning I sure hope) the swap out/in only happens if there is not
> enough RAM to accomodate the working sets of both threads.  So if X and Y
> are the only two active threads, and there is enough RAM to hold both
> working sets, then there would be no swapping.  Right?  Or did I waste my
> money putting a lot of RAM into my new system?

The data and code are not swapped, only CPU state and contents are swapped,
which is about few hundreds bytes to around 10 KBytes, depending on the OS.
CPU cache is not swapped. One would expect this to be fast, but the CPU
performs checks to make sure that one faulty thread or process does not
corrupt other applications and the rest of the system, or bring it down.

> Also, does swapping happen on a thread basis or process basis?  It seems
> to me that it would have to be on a process basis because different
> threads in the same process might be using the same memory.

On a thread bases.
Author
4 Jun 2009 2:42 AM
Mike
eBob.com wrote:

> Also, does swapping happen on a thread basis or process basis?  It seems to
> me that it would have to be on a process basis because different threads in
> the same process might be using the same memory.

A process is a thread - called the primary or main thread.

--
Author
3 Jun 2009 8:27 PM
Nobody
"Mike" <unkn***@unknown.tv> wrote in message
news:uYz$V794JHA.1420@TK2MSFTNGP04.phx.gbl...
> Context switching (CS) is a very expensive Windows and CPU operation. A CS
> is when the WINDOWS:
>
>   - Stops the current thread X in the CPU (preemption),
>   - Swaps out all its code, stacks and memory usage, stores it,
>   - Swaps in the Next thread Y code, stack, memory usage from storage,

You probably know this already, but one can interpret your comments
incorrectly. The code and stack themselves are not swapped, but the
instruction and stack pointers are swapped, along with other registers such
as the stack pointer.

One could use DoEvents to make the GUI responsive, but the user can click on
other things and make events fire.

Some applications have one GUI thread, and one or more worker or background
threads. However, multithreading is more difficult. You have to be careful
when accessing shared resources, or global variables. That's because one
high level language line can be compiled into multiple machine code lines.
For instance, if you have:

If A > B Then
    A -= B
    MsgBox "A is greater than B"
End If

The machine language code may look like this:

    Mov EAX, A ' Set EAX(32 bits) = A
    Cmp EAX, B ' Compare EAX with B, and saves the result to CPU's flags
    JNG End_IF    ' Goto(Jump) to End_IF if not greater than.
    Sub A, B    ' Subtract, A = A - B
    Call AddressOf MsgBox
End_IF:

If A = 5 and B = 3, and another thread switched in the middle of the IF
statement(after the first or second machine line code above) and changed A
to 2, then A<B and the message box is still shown, and A becomes
unexpectedly negative. Similar things happen when you use 64 bit values,
such as Long, on a 32 bit CPU/OS, a simple addition/subtraction or even
assignment takes at least 2 instructions.

The solution is to design multithreading applications carefully. See
SyncLock statement in MSDN, and "See also" part. Here is the online version:

SyncLock Statement:
http://msdn.microsoft.com/en-us/library/3a86s51t.aspx

Multithreading in Visual Basic:
http://msdn.microsoft.com/en-us/library/eed6swsx.aspx
Author
4 Jun 2009 3:17 AM
Mike
Nobody wrote:
> "Mike" <unkn***@unknown.tv> wrote in message
> news:uYz$V794JHA.1420@TK2MSFTNGP04.phx.gbl...
>> Context switching (CS) is a very expensive Windows and CPU operation. A CS
>> is when the WINDOWS:
>>
>>   - Stops the current thread X in the CPU (preemption),
>>   - Swaps out all its code, stacks and memory usage, stores it,
>>   - Swaps in the Next thread Y code, stack, memory usage from storage,
>
> You probably know this already, but one can interpret your comments
> incorrectly.

I agree. Thanks for pointing that out.

> The code and stack themselves are not swapped, but the
> instruction and stack pointers are swapped, along with other registers such
> as the stack pointer.

I should of just said "thread context" but I was trying to be general
- too general. :-)

> You have to be careful when accessing shared resources, or global variables.

Sure, thread synchronization and the various sync methods available is
very important in the area of read/write contention and dead locks
prevention. Multi-thread design is an art and takes many years to
master all the concepts involved.

One of the reasons I decide to more forward with VB.NET is because it
is more optimized than VB6 and has a common footprint with C++/CLR and C#.

Probably after we get some basic applications ported to VB.NET with
the new .NET SDK wrapper I've been working on for the past month or
so, we might look VB.NET threads for some of our simple  multi-thread
hosting applications which are all coded under C/C++.  I am thinking
of porting these set of C/C++ class libraries I contributed to
codeproject.com either to VB.NET or C# one day soon.

     http://www.codeproject.com/KB/IP/cspserver.aspx

We use this for all our internet hosting servers - SMTP, POP3, IMAP,
FTP and other internal client/server protocol servers. They are all
RPC clients to a centralize RPC server that manages the users, files,
mail and security database with a 250 API SDK.

--