我正在编写交易软件,并且需要QoS一种不应该每秒执行10次以上的方法。由于我是C#的初学者并且几乎不熟悉库,我想仔细检查我的代码是否“最佳”。我正在使用Stopwatch
,因为我不知道C#中的任何其他计时器。
Stopwatch updateStopwatch = Stopwatch.StartNew();
private void update()
{
if (updateStopwatch.ElapsedMilliseconds < 100)
{
Console.WriteLine("!skip update " + updateStopwatch.ElapsedMilliseconds);
return;
} else
{
Console.WriteLine("!update");
updateStopwatch.Restart();;
}
// do work here
}
upd 现在看来,秒表非常适合这项任务。然而,可能它会太慢,如果可能的话,DateTime会更好。也卖Stopwatch vs. using System.DateTime.Now for timing events
答案 0 :(得分:2)
使用Stopwatch
的技巧是防止代码更频繁执行的最佳解决方案。正如其他人所说,如果你想确保按计划执行方法,使用Timer
是一个更好的解决方案。
任何基于DateTime
的方法都会从根本上被打破,因为它会在日期更改时失败。这在夏令时开关期间尤其明显。当我们“向前迈进”时,更新可能会快速连续运行两次,因为代码认为自上次更新以来已经过了一个小时。那不算太糟糕。但是当我们“退回”时,更新将暂停一整小时,因为上次更新时间是提前一小时设置的。
如果您的计算机设置为定期从NTP服务器更新其时间,则可能会发生同样的情况,尽管不是那么严重。如果时间提前,则可能会快速连续发生两次更新。如果时间被设置回来,则可能会在时钟被设置的时间内发生更新。
有很多方法可以解决这个问题(例如使用毫秒数的绝对值),但是你只是在一个破碎的解决方案上加上绷带。您不应该依赖DateTime
这样的间隔,因为您的程序无法控制系统时钟 - 它可以随时更改。
Stopwatch
是唯一合理的解决方案,因为它取决于CPU的性能计数器,它只会增加。您没有让某人设置计数器的问题,并且您没有遇到类似Environment.TickCount
之类的翻转问题。
有些人认为Stopwatch
会导致DateTime
没有的性能损失。我的测试表明这是不真实的。
答案 1 :(得分:1)
秒表和计时器是相当昂贵的对象。您可以简单地将DateTime对象作为变量并执行比较。
DateTime lastCheck = DateTime.Now;
private void update()
{
// DateTime.Subtract returns a TimeSpan
int elapsed = DateTime.Now.Subtract(lastCheck).Milliseconds;
if (elapsed < 100)
{
Console.WriteLine("!skip update " + elapsed.ToString());
return;
} else
{
Console.WriteLine("!update");
lastCheck = DateTime.Now;
}
// do work here
}
答案 2 :(得分:1)
我不会使用Stopwatch
或其他任何Timer
- 就像。而只是存储方法调用的时间,并且只有当前和存储时间之间的差异大于100ms时才执行后续调用。
您可以实现一个帮助程序类,以更一般的方式执行此操作:
public class TimedGate
{
private DateTime m_Last;
private TimeSpan m_Gap;
public TimedGate(TimeSpan gap)
{
m_Gap = gap;
}
public bool TryEnter()
{
DateTime now = DateTime.UtcNow;
if (now.Subtract(m_Last) > m_Gap)
{
m_LastEntered = now;
return true;
}
return false;
}
}
像这样使用:
TimedGate m_UpdateGate = new TimedGate(TimeSpan.FromMilliseconds(100));
private void Update()
{
if (m_UpdateGate.TryEnter())
{
Console.WriteLine("!update");
// do work here
}
else
{
Console.WriteLine("!skip update");
}
}
答案 3 :(得分:0)
始终有System.Timer
计时器。
这可能比秒表更容易使用(通常用于衡量事情需要多长时间)。
代码:
var timer = new System.Timers.Timer();
// Hook up the Elapsed event for the timer using a lambda
timer.Elapsed += (o, e) => Console.WriteLine("Timer elapsed");
// Set the Interval to 100 ms
timer.Interval = 100;
// Start the timer.
timer.Enabled = true;
MSDN文档:http://msdn.microsoft.com/en-us/library/system.timers.timer(v=VS.100).aspx