Questions about threaded VB.net

Juason

Member
Joined
Jul 31, 2006
Messages
8
Programming Experience
Beginner
Greetings,

I am a rather new developer of threaded programs in VB.net. Currently my job is having me program a high speed serialized program. One requirement is being able to handle data at a very fast rate, while maintaining accuracy of thread timing.

In attempting to use Windows Timers, I find their accuracy to be poor (55ms or so). I downloaded several custom timers with microsecond accuracy, but unfortunately none of them give handles to tick events. They are just timer.stat, timer.stop, timer.getelapsed - wheras forms/system timers have a tick property and elapsed event.

So I have a while(running) loop to check my timers. Like all thread loops, I need to sleep the thread before looping to ensure I give up the CPU for a bit. Otherwise the 1 looping thread pegs the CPU at ~100%. I need something more accurate than the Millisecond sleep .NET provides.

So, does a Microsecond sleep function exist for VB.net?

I know Linux, Unix, and various C++ libraries have uSleep available. At least, I found some references to them when Googling. Thank you for any help you can provide me with.
 
Well it has been several months, and in that time I have had no luck discovering a means by which to finish this program off.


My program looks like this:

tMain() 'free running thread
{
starttime += 50 ' add 50ms to time

SerialHandler()
RunSequencer()
UpdateDisplay()
DumpData()
Wait(50, starttime)
}

The wait routine looks like this

Wait(delay, starttime)
{
while((usTimer.ElapsedTime - starttime) < 50)
Sleep(1)
}


Excuse my pseudo code errors. What I am looking to do is ensure this thread is run, on average, every 50ms. If windows results in this thread taking longer to execute than 50ms, or sleeps more than 50ms, it will run back to back to back to catch up.

In theory this should work fine, but in reality it doesn't. It is entirely too jumpy and lacks the accuracy I need.

For example. Windows will receive an input from a user to tell the connected device to turn on an output. The sequencer then interprets this input on the next run, makes and sends the packet, then has to wait for a response from the device which can take anywhere from 50-250ms it seems.

Is it possible to run a thread with literally a 1ms delay? I could just make 1 "handler" thread and split those 4 functions into their own threads. ie, only send data when there is data to send, always run the sequencer every 50ms, etc.

How do game developers do it? Obviously games can run at over 100fps - which would indicate an accurate 10ms interrupt somewhere, right? They do NOT seem to just be while(1) loops because most games don't peg the CPU at 100% - they come close, but it isn't 100%.

Thank you for any help you can provide me with. I am used to designing for microcontrollers where the obstacle of a non-real time OS isn't present :p
 
Last edited:
VB.NET, I am actually using MS's free VB.NET Express edition. My apologies for not making that more obvious.
 
VB.NET:
tMain() 'free running thread
{
starttime += 50 ' add 50ms to time

SerialHandler()
RunSequencer()
UpdateDisplay()
DumpData()
Wait(50, starttime)
}

That looks suspiciously like C# to me?
 
Sigh, I did say it was pseudocode... I've switched between vb.net, embedded C on 3 different IDEs today, and assembly :p My brain gets a little fried. Besides, I can't TAB in this window so the braces make things look better. :grunt:

Public thMain as New System.Threading.Thread(AddressOf frmPanel.thMain)

Public Sub tMain() 'free running thread

While 1
starttime += 50 ' add 50ms to time

SerialHandler()
RunSequencer()
UpdateDisplay()
DumpData()
Wait(50, starttime)
End While
End Sub

Yes, I have a way to break and close the thread on program close, but it isn't shown above. Thank you for any help you can give me.
 
The most accurate form of timing possible in VB.Net and windows for that matter is the QueryPerformanceCounter Win32 API. As a developer for C++ i am sure you have already heard of this. The StopWatch class in the .net framework wraps this API but according to documentation it is not a accurate as the native call.
However the nature of managed code would probably defeat the accuracy of such a call due to the stack walk that will be performed. It is possible to optimze a native call with the following attribute.

VB.NET:
System.Security.SuppressUnmanagedCodeSecurity

This will force the call the skip the stack walk, however the JIT will still insist on a link demand to determine whether the caller has the right to call unmanaged code.

In addition the Win32 API also has a function for microsecond acurrate sleep times, the Sub is called 'Sleep' funnily enough!!

VB.NET:
Thread.Sleep(1)

Is probably the .net implementation of this call. Again the unmanaged use would be subject to the same managed code lag that all platform invoke calls are subject to, and my explanation above, of course, applies. It would be possible to Wrap these calls into a class and cause an event to be raised that you could handle given the interval. It is the accuarcy, from a VB.Net point of view that I would question.
 
Back
Top