Perform Screen-Scape of Webbrowser Control in Thread

Most accurate timer in .NET?

For exact time measuring you need to use the Stopwatch class
MSDN

Timer more reliable than System.Threading.Timer

This sounds exactly like thread pool starvation. Look out for long running/blocking jobs running in the thread pool and either rewrite using async io, or in the case of long running CPU intensive jobs, simply don't run these jobs in the thread pool. Run them on their own thread or use a background worker.

Accuracy of the System.Threading.Timers in windows service

The following attempts to resynchronize the timer with the system clock after each interval of a second or longer has elapsed.

// add these fields

private TimeSpan[] _interval;
private DateTime[] _startTime;

// when you create timer1 array, need to initialize the above arrays

int len = timer1.Length;
_interval = new TimeSpan[len];
_startTime = new DateTime[len];

// change SetTimers method as follows;

public void SetTimers(int timer, DataRow row)
{
TimeSpan dueTime;
TimeSpan interval;
SetTimeIntervals(row, out dueTime, out interval);

_interval[timer] = interval;
_startTime[timer] = DateTime.Now + dueTime;
object[] obj = new object[2]{row, timer};
timer1[timer] = new System.Threading.Timer(databaseTrensfer, obj, dueTime, interval);
}

// change databaseTrensfer method as follows

public void databaseTrensfer(object state)
{
object[] obj = (object[])state;
DataRow row = (DataRow)obj[0];
string alarmType = Convert.ToString(row["EBase"]);
if (alarmType != "Milisecond" && alarmType != "Once")
{
int timer = (int)obj[1];
DateTime dt = DateTime.Now;
long elapsedMs = Convert.ToInt64((dt - _startTime[timer]).TotalMilliseconds);
long intervalMs = Convert.ToInt64(_interval[timer].TotalMilliseconds);
long remainder = elapsedMs % intervalMs;
if (remainder != 0L)
{
timer1[timer].Change(_interval[timer] - TimeSpan.FromMilliseconds(remainder), _interval[timer]);
}
}
//code
}

Implementing a loop using a timer in C#

Use a construct like this:

Timer r = new System.Timers.Timer(timeout_in_ms);
r.Elapsed += new ElapsedEventHandler(timer_Elapsed);
r.Enabled = true;
running = true;
while (running) {
// do stuff
}
r.Enabled = false;

void timer_Elapsed(object sender, ElapsedEventArgs e)
{
running = false;
}

Be careful though to do this on the UI thread, as it will block input.

What kind of timer is most suitable for MIDI timing?

Although I have not had the privilege of coding for commercial DAW projects specifically, I do have experience in coding for scenarios where the accurate timing of events is important, including MIDI processing/routing.

Your assumption is correct. Well-coded MIDI sequencers use the Windows Multimedia Timer to schedule the sending of MIDI messages to MIDI devices.

Microsoft's Multimedia Timer Reference actually mentions MIDI sequencing as an example use:

These timer services are useful for applications that demand high-resolution timing. For example, a MIDI sequencer requires a high-resolution timer because it must maintain the pace of MIDI events within a resolution of 1 millisecond.

How to use the timer is for another topic, I won't get into that here. But I'd like to point out a few things:

  • All modern hardware supports a timer resolution of 1 millisecond, it's basically a given, but you should still call timeGetDevCaps to make sure before calling timeBeginPeriod.

  • Using the multimedia timer, at 1 millisecond resolution, will have the effect of quantizing your MIDI messages to a 1 millisecond grid +/- some variance/jitter. In the vast majority of cases this is a non-issue because that is still a sufficiently fine resolution to provide reasonably nuanced timing, so far as musical timing goes anyway. If you absolutely need sub-millisecond timing, you will have to do as @iinspectable suggests - use the timer to get "close" and then spin to precisely time the sending of your MIDI messages. However, this approach comes at a cost. I don't know what your intentions are for the app, but should you have several simultaneous MIDI tracks playing, each with continuous controllers and pitch bend, you'll find your app spinning all the time and you'll peg a CPU core to 100% which is just plain bad.

  • Do look into Windows' Multimedia Class Scheduler Service to get prioritized access to CPU resources for your MIDI playback thread.

  • Don't be discouraged by comments from @iinspectable. You can absolutely do high-performance MIDI sequencing using C#/.NET. Your only concern needs to be that of the garbage collector unpredicatably pausing your app. You can always code in a way that minimizes GC (e.g. use structs not classes, don't create/destroy anything during playback). Also consider using GC.TryStartNoGCRegion to, for example, prevent GC pauses during playback.

How do I run a function with precise timing?

.NET, C#, and even Windows in general are not realtime OSes suitable for very fine timing.

The worst options include using the Timer classes and Thread.Sleep().

You can measure timing fairly accurately using the Stopwatch class, but in terms of accurately waiting for a set amount of time to pass.. there's no built-in mechanism.

If you could outline exactly what you are trying to do, assuming it's not motion control, hardware interfacing etc, there is probably a better solution than relying on very accurate timers.

Update; Neal: if you are interfacing with hardware in a timing-sensitive way, you should use a different solution. You can do a tight loop with Stopwatch, but it will use lots of CPU for as long as you do. And it won't be accurate enough, probably. E.g.: a PIC chip, an FPGA, an I/O card or interface, anything else basically.



Related Topics



Leave a reply



Submit