Waitable Timer in C# ?

G

Guest

I'm coming from Win32 world. Now, I'm porting the existing code to C#. I
cannot find the equivalent Win32 Waitable Timer in C#. I have a thread to
perform some task periodically like following:

While(...)
{
Do something ...

SetWaitableTimer(hTimer, ...);
WaitForSingleObject(hTimer, ...);
}

Could anybody tell me how to implement a waitable timer so a thread can
actually wait for it?

Thanks!
 
P

Peter Duniho

I'm coming from Win32 world. Now, I'm porting the existing code to C#. I
cannot find the equivalent Win32 Waitable Timer in C#. I have a thread to
perform some task periodically like following:

While(...)
{
Do something ...

SetWaitableTimer(hTimer, ...);
WaitForSingleObject(hTimer, ...);
}

Could anybody tell me how to implement a waitable timer so a thread can
actually wait for it?

I don't know of any .NET class that duplicate the functionality exactly.
However, do you really need the APC behavior of the Win32 waitable timer
object? That is, is it important that the timer completion routine
execute on the same thread but without an explicit call in your code?

In .NET, you do have other timing options. System.Timers.Timer and
System.Threading.Timer both provide similar timing functionality, with the
main difference being that when the timer fires the delegate given to the
timer is run on another thread. If all you really want is to wait a
specific time, then you could just use a call to Sleep(). If you really
want to block while waiting for another thread to run the timer delegate,
you could wait on an event instance and have the timer delegate set the
event.

So, depending on what functionality you really need, you either can't do
it in .NET (AFAIK) or you can do it in slightly different ways. It seems
to me that in most cases, an application doesn't really need a Win32
waitable timer object, but you could be porting one of the rare blocks of
code that does. Knowing exactly what the timer's being used for would be
helpful in providing useful options for you.

Pete
 
G

Guest

For starters, I'd take a look at the ManualResetEvent class and it's various
WaitOne, etc. overloaded methods.
Peter
 
G

Guest

I thought about doing that in the following way:

Set the event
WaitOne() the event and set the time interval in it to let the wait expire
to simulate the waitable timer.

or, even use the Sleep.

But, the "timer" inside WaitOne and Sleep are not as accurate as in the
Win32 waitable timer. The 55ms resolution is not good enough for this
application. It has to be within 10ms.

Yi
 
G

Guest

If you really want to block while waiting for another thread to run the
timer >delegate, you could wait on an event instance and have the timer
delegate set >the event.

I like this idea! I think it is a great way to simulate the Win32 waitable
timer behavior by combining the .Net timer and the event object.
 
P

Peter Duniho

timer >delegate, you could wait on an event instance and have the timer
delegate set >the event.

I like this idea! I think it is a great way to simulate the Win32
waitable timer behavior by combining the .Net timer and the event
object.

Yes, but if all you're doing is causing the thread to pause and then
resume after a specific amount of time, all you really need is to call
Sleep().

I mean, I'm glad you liked my suggestion and all, but please don't use it
unless you really need to do some processing in the callback other than
releasing the thread. :)

Pete
 
P

Peter Duniho

[...]
But, the "timer" inside WaitOne and Sleep are not as accurate as in the
Win32 waitable timer. The 55ms resolution is not good enough for this
application. It has to be within 10ms.

I don't know that you'll get better than that from .NET. Even if you use
the suggestion to have the Timer class set an event, and even if the Timer
class offers the resolution you want (and I don't know that it does),
because it's releasing a different thread by setting the event handle, you
have to deal with the thread scheduling and the resulting inaccuracy (that
is, the thread being released may or may not run the instant its event
handle is set).

Pete
 
G

Guest

You got me thinking here. I planed to use a manual event and a system timer ,
which according to the .NET document, has the high resolution. Adding the
thread context switching time, it might introduce some latency.....

--
Eric


Peter Duniho said:
[...]
But, the "timer" inside WaitOne and Sleep are not as accurate as in the
Win32 waitable timer. The 55ms resolution is not good enough for this
application. It has to be within 10ms.

I don't know that you'll get better than that from .NET. Even if you use
the suggestion to have the Timer class set an event, and even if the Timer
class offers the resolution you want (and I don't know that it does),
because it's releasing a different thread by setting the event handle, you
have to deal with the thread scheduling and the resulting inaccuracy (that
is, the thread being released may or may not run the instant its event
handle is set).

Pete
 
P

Peter Duniho

Does Sleep() have the resolution around 55ms?

The resolution of Sleep() depends on the resolution of the system clock.

Using native Windows API, you can use timeGetDevCaps to find the current
resolution of the timer, and timeBeginPeriod to adjust it. I don't know
whether similar access to the timer resolution is available in .NET.
Maybe through WMI? Not something I've done before so it's not something
I'm familiar with.

All that said, you should of course always keep in mind that whatever the
resolution of the timer being used, because of the way Windows handles
thread scheduling, there is *never* a guarantee that you will get to run
your thread exactly when you want to.

Pete
 
W

Willy Denoyette [MVP]

Eric said:
Does Sleep() have the resolution around 55ms?
--

Sleep has no real resolution, calling Sleep gives up the current thread's quantum and puts
the thread asleep for aprox. the time specified as argument (if NOT 0), or, if the time
specified is lower than a thread's quantum, for the remaining of that quantum.
A thread's quantum is a multiple of the RTC interval, on modern systems this interval is per
default, 10 or 15.6 msecs. (multi-cpu) and can be determined by calling
GetSystemTimeAdjustment. The interval can also be changed on a per thread basis by calling
"timeBeginPeriod" paired with "timeEndPeriod" Multimedia Timer API's.

Say you have a Thread quantum of 10msecs. and a thread that has run for 3msecs. before
calling Sleep(5), in this case the thread will sleep for at least 10 - 3 = 7 msecs.
A Sleep(18) on a system with 15.6 msecs interval, will sleep for anything between 15.6 and
31.2 msecs.
Notice I said "at least", this is not guaranteed, other runable threads with higher or equal
priorities can drastically increase the total sleep time of your thread.

Willy.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top