1 to 10ms delay

  • Thread starter Thread starter paul f
  • Start date Start date
P

paul f

Hi,
Is it possible create a function that I can call like msDelay(2) to
run a 2 millisecond delay?
The Thread.Sleep function cannot go below 10ms...
 
paul said:
Hi,
Is it possible create a function that I can call like msDelay(2) to
run a 2 millisecond delay?
The Thread.Sleep function cannot go below 10ms...

paul, I just tried several ways to attempt to solve this.
The first was to use a Timer object and call the tick on 2 ms.
I have a simple application that uses two TextBoxes to show the start
and stop times, and a third for the difference. A button kicks this all off.

However, the difference would always hit at about 15.6 or 31 ms.

So, I tried to take matters into my own hands. I would continue to poll
the DateTime.Now object until my difference was just above 2 ms. Well,
I could get 0 or 15.6 ms. I think that the DateTime.Now object, and
hence perhaps the .NET Runtime can only handle so fine of a tuning for
timing purposes.

While you could get close to the second or minute pretty accurately, it
would seem that the .NET Runtime is not very well suited for Real-time
and High-Precision timing tasks.

Below is the code I was using to try out some of these ideas. It is
Form1.cs from a standard WinForms template in Visual Studio.

<!-- ----------------------------------------

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication2
{
public partial class Form1 : Form
{
#region Form1.Designer.cs
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;

/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be
disposed; otherwise, false.</param>
protected override void Dispose( bool disposing )
{
if ( disposing && (components != null) )
{
components.Dispose();
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.timer1 = new System.Windows.Forms.Timer( this.components );
this.button1 = new System.Windows.Forms.Button();
this.textBox1 = new System.Windows.Forms.TextBox();
this.textBox2 = new System.Windows.Forms.TextBox();
this.textBox3 = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// timer1
//
this.timer1.Interval = 2;
//
// button1
//
this.button1.Location = new System.Drawing.Point( 12, 12 );
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size( 50, 46 );
this.button1.TabIndex = 0;
this.button1.Text = "Go!";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler( this.button1_Click );
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point( 68, 12 );
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size( 183, 20 );
this.textBox1.TabIndex = 1;
//
// textBox2
//
this.textBox2.Location = new System.Drawing.Point( 68, 38 );
this.textBox2.Name = "textBox2";
this.textBox2.Size = new System.Drawing.Size( 183, 20 );
this.textBox2.TabIndex = 2;
//
// textBox3
//
this.textBox3.Font = new System.Drawing.Font( "Microsoft Sans Serif",
26F, System.Drawing.FontStyle.Regular,
System.Drawing.GraphicsUnit.Point, ((byte)(0)) );
this.textBox3.Location = new System.Drawing.Point( 258, 12 );
this.textBox3.Name = "textBox3";
this.textBox3.Size = new System.Drawing.Size( 77, 47 );
this.textBox3.TabIndex = 3;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 13F );
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size( 347, 68 );
this.Controls.Add( this.textBox3 );
this.Controls.Add( this.textBox2 );
this.Controls.Add( this.textBox1 );
this.Controls.Add( this.button1 );
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout( false );
this.PerformLayout();

}

#endregion

private System.Windows.Forms.Timer timer1;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.TextBox textBox2;
private System.Windows.Forms.TextBox textBox3;

#endregion

public Form1()
{
InitializeComponent();
timer1.Tick += new EventHandler( timer1_Tick );
}

double start,stop,difference;

#region Method 1 (~15-30 ms)
//void timer1_Tick( object sender, EventArgs e )
//{
// timer1.Stop();
// stop = DateTime.Now.TimeOfDay.TotalMilliseconds;
// difference = stop - start;

// textBox1.Text = start.ToString();
// textBox2.Text = stop.ToString();
// textBox3.Text = difference.ToString();
//}

//private void button1_Click( object sender, EventArgs e )
//{
// start = DateTime.Now.TimeOfDay.TotalMilliseconds;
// timer1.Start();
//}
#endregion

#region Method 2
void timer1_Tick( object sender, EventArgs e )
{

}

private void button1_Click( object sender, EventArgs e )
{
start = DateTime.Now.TimeOfDay.TotalMilliseconds;
//int i = 0; // B
do
{
stop = DateTime.Now.TimeOfDay.TotalMilliseconds;
difference = stop - start;
} while ( difference < 2 ); // A
// i++; // B
//} while ( i < 6000 ); // B

textBox1.Text = start.ToString();
textBox2.Text = stop.ToString();
textBox3.Text = difference.ToString();
}
#endregion

}
}

---------------------------------------- -->
 
paul f said:
Is it possible create a function that I can call like msDelay(2) to
run a 2 millisecond delay?
The Thread.Sleep function cannot go below 10ms...

No. User mode timers can only be checked at the hardware timer interrupt,
which is either 10ms or 16ms depending on your system configuration.

The Win32 API timeBeginPeriod can reduce that interval to as low as 1ms,
but it extracts a heavy toll on performance.

Most of the other replies to your message are telling you how to do more
accurate interval timing, but those methods don't help you do delays.

Why do you need shorter delays?
 
Tim Roberts said:
No. User mode timers can only be checked at the hardware timer interrupt,
which is either 10ms or 16ms depending on your system configuration.

The Win32 API timeBeginPeriod can reduce that interval to as low as 1ms,
but it extracts a heavy toll on performance.

There is a performance hit, but I don't think you could describe it as heavy
since the Pentium first came out, and certainly not these days.

If the user is actually using your application for useful work, the
performance penalty of the 1ms timer interrupt is likely to be one
thousandth of one percent or thereabouts.

There's probably a bigger impact on battery life for laptops because the CPU
can't sleep as efficiently with a shorter timer interrupt. This is only a
concern if running as a background process, as long as the user is
interacting with the computer it won't be spending much idle time anyway.
No I said that wrong. The computer will still be idling quite a bit under
most task loads, but it will be waking frequently anyway
(USB/network/whatever interrupts) and you may not be adding extra wakes.
 
Back
Top