Windows系统的调度时间片是15ms,且不稳定,这为精确、快速的任务带来很多痛苦。在没有硬件中断源的情况下,多媒体定时器还真是一个不错的选择,我找到了一个C#下可以用的多媒体定时器的库(下载地址在文末),进行了1ms周期的测试,并用c#的timer控件进行了对比测试,差别非常大,多媒体定时器可以说很稳定了。
1、多媒体定时器周期测试结果
经过将近一小时的1ms中断运行,期间并未刻意保持系统空闲,而是一直在打开2个VS2019进行编程工作。实际时间间隔统计如下:
其中小于等于2ms的占比为97.92%,2ms~3ms的占比为2.03%,超过3ms的占比仅为0.05%。
2、c#timer控件的周期测试结果
这是用c#里的timer中断的测试结果,设置了15ms周期,结果惨不忍睹:
3、源代码
using System;
using System.Diagnostics;
using System.Windows.Forms;
using Dongzr.MidiLite;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
static MmTimer mm1;
int interval;
long count;
long[] cArray = new long[10];//计数数组
double[] pArray = new double[10];//百分比数组
Stopwatch sw = new Stopwatch();//精确计时器
long timeTickOld, timeTickNow,intervalAct;
double intervalms;
private void btStart_Click(object sender, EventArgs e)
{
if(int.TryParse(tbInterval.Text,out interval))
{
interval = Math.Max(1, interval);
}
else
{
interval = 1;
}
tbInterval.Text = interval.ToString();
for(int i = 0; i < 7; i++)
{
cArray[i] = 0;
pArray[i] = 0;
}
count = 0;
countUpdate();
mm1.Interval = interval;
mm1.Start();
//timer2.Interval = interval;
//timer2.Enabled = true;
timeTickOld = sw.ElapsedTicks;
}
private void Form1_Load(object sender, EventArgs e)
{
mm1 = new MmTimer();
mm1.Mode = MmTimerMode.Periodic;
mm1.Tick += new EventHandler(mm1_tick);
sw.Start();
}
void mm1_tick(object sender, EventArgs e)
{
timeTickNow = sw.ElapsedTicks;
intervalAct = timeTickNow - timeTickOld;
intervalms = (double)intervalAct / 10000;
timeTickOld = timeTickNow;
count++;
if (intervalms < interval)
{ cArray[6] += 1;}
else if (intervalms == interval)
{cArray[0] += 1;}
else if (intervalms <= interval + 1)
{cArray[1] += 1;}
else if (intervalms <= interval + 2)
{cArray[2] += 1;}
else if (intervalms <= interval + 3)
{cArray[3] += 1;}
else if (intervalms <= interval + 4)
{cArray[4] += 1;}
else
{cArray[5] += 1;}
}
private void timer1_Tick(object sender, EventArgs e)
{
countUpdate();
}
private void timer2_Tick(object sender, EventArgs e)
{
mm1_tick(null, null);
}
private void btReset_Click(object sender, EventArgs e)
{
for (int i = 0; i < 7; i++)
{
cArray[i] = 0;
pArray[i] = 0;
}
count = 0;
countUpdate();
}
private void btStop_Click(object sender, EventArgs e)
{
mm1.Stop();
timer2.Enabled = false;
}
void countUpdate()
{
for(int i = 0; i < 7; i++)
{
pArray[i] = (double)cArray[i] / (double)count;
}
LBCN.Text = cArray[0].ToString();
LBCN1.Text = cArray[1].ToString();
LBCN2.Text = cArray[2].ToString();
LBCN3.Text = cArray[3].ToString();
LBCN4.Text = cArray[4].ToString();
LBCNBIG4.Text = cArray[5].ToString();
LBCNS0.Text = cArray[6].ToString();
LBPN.Text =string.Format("{0:f2}%", pArray[0]*100);
LBPN1.Text = string.Format("{0:f2}%", pArray[1] * 100);
LBPN2.Text = string.Format("{0:f2}%", pArray[2] * 100);
LBPN3.Text = string.Format("{0:f2}%", pArray[3] * 100);
LBPN4.Text = string.Format("{0:f2}%", pArray[4] * 100);
LBPNBIG4.Text = string.Format("{0:f2}%", pArray[5] * 100);
LBPNS0.Text = string.Format("{0:f2}%", pArray[6] * 100);
lbCount.Text = count.ToString();
lbIntervalLast.Text = string.Format("{0:f2}", intervalms);
}
}
}
多媒体定时器下载地址:点击打开链接
2021年1月8日