【问题标题】:Stopwatch: measuring time and restart immediately without race condition秒表:测量时间并立即重新启动,无需竞争条件
【发布时间】:2013-06-19 03:06:28
【问题描述】:

我对 .net 框架中的 Stopwatch 类有疑问。我想测量循环迭代所花费的时间(游戏中的时间)

Stopwatch timer = new Stopwatch();
timer.Start(); // Edited this in, forgot about that
while(true)
{
    var timespan = timer.Elapsed;
    timer.Restart();
    // do something with the timespan

    // Do some work here
}

我担心在测量和重新启动之间可能会发生上下文切换,并且会丢失一些“时间”。 有谁知道以原子方式测量和重新启动计时器的方法?

编辑:也欢迎没有秒表的解决方案

【问题讨论】:

  • 把 timer.start 放在 while 循环之上,timer.stop 放在下面并创建时间跨度变量 = timer.Ellapsed,如果它记录 while 循环时间。
  • 我不想测量整个 while 循环,而只想测量每次迭代。这用于游戏循环,其中“上下文切换时间”可能并不重要。只是我想让它尽可能精确。并想一想:如果我的线程是低优先级并且高优先级线程启动并且我的低优先级在 2 分钟内没有 cpu 周期或其他什么(只是弥补:))怎么办。这会对测量产生很大影响。

标签: c# .net multithreading


【解决方案1】:

您不必重新启动计时器。您可以只记住变量中 Elapsed 的最后测量值,然后始终取差值。类似的东西(你还必须照顾第一次迭代):

Stopwatch timer = new Stopwatch();
var lastElapsed = timer.Elapsed;
while(true)
{
    var newLastElapsed = timer.Elapsed;
    var timespan = newLastElapsed - lastElapsed;
    lastElapsed = newLastElapsed;
    // do something with the timespan

    // Do some work here
}

但是,您为什么要关心在测量 Elapsed 和重新启动计时器之间经过了一段时间?您是否对仅衡量“在这里做一些工作”部分感兴趣,或者也衡量“使用时间跨度做某事”部分?

【讨论】:

  • 我刚刚也来到了这个解决方案。我想要做的实际上是模拟一个计时器。我将每次迭代的时间添加到另一个时间跨度,当这个时间跨度超过某个阈值时,就会触发一个方法。在我的情况下,这是一个具有固定时间步长的游戏循环,以不同的时间间隔触发更新和绘制
  • 虽然这当然是可行的,但甚至没有任何理由让Stopwatch 实例在内部进行减法运算。只需执行 lastTimestamp = Stopwatch.GetTimestamp();newTimestamp = Stopwatch.GetTimestamp(); timespan = TimeSpan.FromTicks(newTimestamp - lastTimestamp); lastTimestamp = newTimestamp; 即可消除首次创建 Stopwatch 对象时对时间戳的不必要的重复减法。
【解决方案2】:
Stopwatch timer = new Stopwatch();
timer.Start();
var previous = timer.elapsed;
while(!done)
{
    var current = timer.Elapsed;
    var elapsed = current - previous;
    previous = current;
    // use elapsed
    // do the rest of your work
}

抱歉格式化,等我在真正的电脑上修复它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多