Hi all,
I'm writing a .net Com object to read messages from an external bus.
Also, under certain situations, I output messages to the bus in order
to generate bus load, for testing purposes. An idea of my code is
supplied below, and as you can see I use Stopwatch to generate an
accurate timer. DoLoop is my timer callback and it is called with an
interval of 20ms. When doing the bus load I need the timer to perform
as well as possible, so I use Sleep(0) while polling the stopwatch. As
you can imagine, this sends the processor load to 100%. When not doing
the bus load, I use Sleep(1). This results in the usual approx. 15ms
sleep, depending on the system. This is fine - at the moment at
least...
So I have tried 3 variations of my code -
1. The code below works well, but when this.busLoad.IfStarted() is
true, the computer is very non responsive.
2. I've also tried using Sleep(1) while also doing the bus load.
Result: Bus load is less reliable as messages are not outputted as
periodically as in 1 above.
3. Keeping the thread priority at normal while using Sleep(0). This
works well, except when I start doing things with other applications
etc. and then I start to see the same behavior as in 2.
Anyway, I am wondering if my approach is a good one with regard to the
way I am implementing my callback timer. Can you think of any issues
based on this implementation - I'm aware that my timer will not run
exactly periodically, but it would be nice to run it as periodically
as is possible. One other idea I had was to change the thread priority
depending on how soon the it was until the callback was to be called.
Maybe that would be complete overkill.
using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Threading;
using System.Collections.Generic;
namespace Mine
{
public class Main
{
Thread timerLoop;
Stopwatch watch = new Stopwatch();
bool keepTiming = true;
int interval;
public Main(int interval)
{
this.interval = interval;
timerLoop = new Thread(new ThreadStart(DoLoop));
timerLoop.Priority =
System.Threading.ThreadPriority.Normal;
timerLoop.Start();
timerLoop.Priority =
System.Threading.ThreadPriority.Highest;
}
/// <summary>
/// Stop Timer
/// </summary>
public void Stop()
{
keepTiming = false;
timerLoop.Join();
}
private void DoLoop()
{
int threadSleepTime = 0;
while (keepTiming)
{
watch.Reset();
watch.Start();
if (this.busLoad.IfStarted()==true)
{
this.busLoad.GenerateBusLoad();
threadSleepTime = 0;
}
else
threadSleepTime = 1;
// Call Read Message Function
while (watch.ElapsedMilliseconds < interval)
{
Thread.Sleep(threadSleepTime);
}
}
}
}
}
|