volatile DateTime

vto*_*ola 10 .net c# multithreading synchronization volatile

由于DateTime不能声明为volatile,这是对的吗?:

        private DateTime _time;
        public DateTime Time
        {
            get
            {
                Thread.MemoryBarrier();
                return _time;
            }
            set
            {
                _time = value;
                Thread.MemoryBarrier();
            }
        }
Run Code Online (Sandbox Code Playgroud)

该属性可以从不同的线程访问,所以我想确保它们始终获得最新版本,而不使用争用(锁定).

编辑:

  • 我有一组难以创建的项目,每个项目都有一个名为CreationTime的DateTime属性,指示何时创建此项目.它被初始化为DateTime.UtcNow.
  • 每次访问项目时,该属性都会更新为DateTime.UtcNow.
  • 有一个线程,在线程计时器中及时执行,检查是否(DateTime.UtcNow + 1小时)> item.CreationTime,如果为true则删除该项.

我想确保当"删除线程"进入集合时,所有项目都有最新的"最后访问"DateTime,因此我可以避免再次创建项目,因为缓存保持该值几毫秒:d

提前致谢.

Moo*_*ice 13

正是.

但是,你有另一种选择.将时间存储为Int64滴答计数,并用于InterlockedExchange设置.然后,线程可以DateTime使用Int64构造函数构造自己的线程,不会产生争用,也不会产生锁定.

编辑:

鉴于您提供了更多信息,现在提供示例更容易.

public class Cache
{
    class CacheEntry
    {
        private Int64 m_Touched;

        public CacheEntry()
        {
            Touch();
        }

        public void Touch() 
        {
            System.Threading.Interlocked.Exchange(ref m_Touched, DateTime.Now.Ticks);
        }

        public DateTime Touched
        {
            get
            {
                return new DateTime(Interlocked.Read(ref m_Touched));
            }
        }
    } // eo class CacheEntry
} // eo class Cache
Run Code Online (Sandbox Code Playgroud)

  • 最好使用`ToBinary` /`FromBinary`而不是仅存储原始刻度,以便保留`DateTimeKind`.(虽然我认为OP应该只使用一个`lock`和一个普通的`DateTime`而不是试图过于聪明.) (3认同)
  • 虽然可能,但这两个建议听起来可能涉及很多冗余转换.当然,这取决于DateTime值有多少消费者. (2认同)
  • @ Sensai76,也许但是我怀疑转换会是一个麻烦的开销(虽然很难说不知道其他线程如何使用它),并且说,它将比某种锁定更少的开销. (2认同)