Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
422 views
in Technique[技术] by (71.8m points)

c# - System.Timers.Timer only gives maximum 64 frames per second

I have an application that uses a System.Timers.Timer object to raise events that are processed by the main form (Windows Forms, C#). My problem is that no matter how short I set the .Interval (even to 1 ms) I get a max of 64 times per second.

I know the Forms timer has a 55 ms accuracy limit, but this is the System.Timer variant, not the Forms one.

The application sits a 1% CPU, so it's definitely not CPU-bound. So all it's doing is:

  • Set the Timer to 1&nsp;ms
  • When the event fires, increment a _Count variable
  • Set it to 1&nsp;ms again and repeat

_Count gets incremented a maximum of 64 times a second even when there's no other work to do.

This is an "playback" application that has to replicate packets coming in with as little as 1-2 ms delay between them, so I need something that can reliably fire 1000 times a second or so (though I'd settle for 100 if I was CPU bound, I'm not).

Any thoughts?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Try Multimedia Timers - they provide greatest accuracy possible for the hardware platform. These timers schedule events at a higher resolution than other timer services.

You will need following Win API functions to set timer resolution, start and stop timer:

[DllImport("winmm.dll")]
private static extern int timeGetDevCaps(ref TimerCaps caps, int sizeOfTimerCaps);

[DllImport("winmm.dll")]
private static extern int timeSetEvent(int delay, int resolution, TimeProc proc, int user, int mode);

[DllImport("winmm.dll")]
private static extern int timeKillEvent(int id);

You also need callback delegate:

delegate void TimeProc(int id, int msg, int user, int param1, int param2);

And timer capabilities structure

[StructLayout(LayoutKind.Sequential)]
public struct TimerCaps
{
    public int periodMin;
    public int periodMax;
}

Usage:

TimerCaps caps = new TimerCaps();
// provides min and max period 
timeGetDevCaps(ref caps, Marshal.SizeOf(caps));
int period = 1;
int resolution = 1;
int mode = 0; // 0 for periodic, 1 for single event
timeSetEvent(period, resolution, new TimeProc(TimerCallback), 0, mode);

And callback:

void TimerCallback(int id, int msg, int user, int param1, int param2)
{
    // occurs every 1 ms
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...