【问题标题】:Good practice for keeping track of timestamps跟踪时间戳的良好做法
【发布时间】:2017-11-30 17:02:33
【问题描述】:

什么被认为是跟踪例如的良好做法?在进行串行通信的应用程序中收到消息的时间戳?

假设应用程序每秒在串行端口上接收流式消息 20 次。并且您想跟踪收到的消息的时间戳。一种方法可能是这样的:

public class SerialPortHandler {
    private DateTime _rxTimestamp;
    private SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) {
        _rxTimestamp = DateTime.Now;
        // Collect bytes in RX buffer and do stuff...
    }
}

但是,每次接收到数据时,_rxTimestamp 将被设置为 DateTime 对象的新实例。我知道 C# 有垃圾收集,可以处理内存中未引用的对象。但是这种方式是否完全符合良好的 OOP 实践,或者在计算机资源方面是否会被认为是浪费?

【问题讨论】:

  • 你想用时间戳做什么?
  • @abto 这有关系吗?但是为了争论,假设我正在做异步通信,并且需要检查是否在给定的时间限制内收到了消息。
  • 没有任何垃圾收集实例(它是一种值类型),但这里 IMO 的要点是准确性(您没有纯日期时间)和 UTC(您当时没有使用切换到/从 DST 切换时,您将有跳跃/孔)。每秒 20 次处于系统时间的边缘。您可以将它与秒表一起用作参考(UTC 时间!)
  • 如果你想用时间戳记录每个请求,那么它没有实际意义。实际上,如何您设法持久化日志更多的是(I/O)瓶颈恕我直言 - 例如我是每秒“写入某个持久层”20 次(还是“批量”)?
  • @Oystein 如果只是为了跟踪数据,通常的方法是使用递增的 Id,例如使用 Interlocked 递增的 Int32 以确保线程安全。至于“每 50 毫秒覆盖一个对象”——这完全没有问题。

标签: c# oop


【解决方案1】:

就内存使用而言,您的具体情况没有问题。 System.DateTimea value type 并且您的分配不涉及装箱值,因此没有创建 GC 需要收集的对象。唯一发生的事情是设置了字段_rxTimestamp 的值。

您甚至可以争论 创建DateTime 的实例是否是正确的术语。发生的情况是当前日期和时间的 64 位值被放入 _rxTimestamp 的内存点。旧值被简单地覆盖。

【讨论】:

  • “我正在做异步通信,需要检查是否在给定的时间限制内收到了消息”。我认为,这个答案与问题无关。 Questionar 知道 _rxTimestamp 值被覆盖,他正在寻找并考虑一个好的解决方案来执行目的。
  • @Rainman:你误解了这个问题。 OP 知道 reference 会被覆盖,但显然(并且明确)担心保留在内存中的对象。您在 OP 中使用的引用是为了解释代码的总体目的,而不是具体问题。
  • @Sefe 好答案。但是,您能否也提一下关于使用新对象实例定期覆盖字段、将未引用的对象留在内存中的注意事项?
  • @Oystein:你想让我写什么?你有什么特别想知道的吗?这个问题的问题在于它很难概括,因为它取决于对象大小、内存和性能要求等因素。
  • @Oystein:很难概括一个特定问题的答案。我不反对延长我的答案,我只是不知道如何,不要让它太长或太不精确。
猜你喜欢
  • 2022-10-24
  • 1970-01-01
  • 2011-06-18
  • 2014-11-24
  • 1970-01-01
  • 1970-01-01
  • 2011-07-08
  • 1970-01-01
  • 2021-12-18
相关资源
最近更新 更多