我有一个数据列表和需要处理的时间。时间通常约为一秒(或更短)(它们各不相同)但需要在相当接近的时间运行。我已经尝试让线程休眠一小段时间,但是在睡眠后恢复线程会产生一些开销,导致短暂的延迟。有一种可靠的方法可以通过相对简单的代码获得我所需的准确度吗?
答案 0 :(得分:2)
在多任务操作系统中,提高进程的优先级可能会有所帮助,但除非您的操作系统支持real time,否则无法在几毫秒的时间内精确地进行时序保证。
答案 1 :(得分:1)
如何在单独的线程上使用System.Threading.Timer
类?
答案 2 :(得分:1)
尝试使用StopWatch对象。我创建了一个假设的DataAndTime对象
public class DataAndTime
{
private string m_Data = "";
public string Data {
get { return m_Data; }
set { m_Data = value; }
}
private int m_TimeInMilliSeconds = 0;
public int TimeInMilliSeconds {
get { return m_TimeInMilliSeconds; }
set { m_TimeInMilliSeconds = value; }
}
}
其中TimeInMilliSeconds是您希望处理数据列表的精确间隔(以毫秒为单位)。然后我创建了两个对象,一个堆栈和一个秒表:
private Stack<DataAndTime> aStack = new Stack<DataAndTime>();
private Stopwatch aStopWatch = new Stopwatch()
您可以使用集合或列表而不是堆栈或其他任何内容。我用100个DataAndTime对象填充堆栈:
public void PopulateStack{
for (int Index = 0; Index <= 100; Index++) {
DataAndTime NewDataAndTime = new DataAndTime();
NewDataAndTime.Data = (string)Index + " AS A STRING";
NewDataAndTime.TimeInMilliSeconds = 1000 - Index;
aStack.Push(NewDataAndTime);
}
}
这个想法与停止和启动秒表的物理模拟相同,并且在经过的毫秒过去的相关时间之前没有做任何事情。瞧。共约40行代码:
public void ProcessData{
{
while (aStack.Count > 0) {
aStopWatch.Reset();
aStopWatch.Start();
DataAndTime StackPop = aStack.Pop;
string CallBackData = StackPop.Data;
int CallBackTime = StackPop.TimeInMilliSeconds;
while (aStopWatch.ElapsedMilliseconds < CallBackTime) {
}
Console.WriteLine("Time elapsed for " + CallBackData + " " + CallBackTime + ": " + aStopWatch.ElapsedMilliseconds);
aStopWatch.Stop();
}
}
答案 3 :(得分:0)
在完全时间开始处理的最可靠方法是阻止到确切的时间。在伪代码中:
futuretime = now + 1 second;
while (now < futuretime)
{
// do nothing
}
// 1 second has elapsed, start processing
但是,当然,只要你处于while循环中,这就会占用CPU。
或者你可以半途而废,做一个线程睡眠,直到你在目标时间的50+毫秒内,然后才进行阻塞等待。你不会那么多地占用CPU,你可以合理地确定你的线程会在1秒钟到来之前被激活。
This article对Windows API提供的计时功能进行了非常全面的评估。最后,它得出结论:
...考虑一个混合方案,你可以调用Sleep(1)...每当你需要传递超过1毫秒的时间,然后只进入QueryPerformanceCounter 100%-busy循环来完成最后一个&lt; ;你需要的延迟的1/1000秒。这将为您提供超精确的延迟(精确到10微秒),并且CPU使用率极低。
答案 4 :(得分:0)
如果您绝对需要在时间上保持较短的时间差异,则可能需要查看使用DirectX API。 DirectX 9.0c具有Managed .NET接口,可以访问高可靠性时钟。我曾经用过这种音乐来播放一些不到1毫秒的音乐来开始和停止音乐,而且效果很好。
但是,应用程序将接管计算机,因为共享将关闭时间,然后您可能也在使用计时器。