易失性日期时间
由于DateTime
不能声明为易失性
,这是对的吗?
private DateTime _time;
public DateTime Time
{
get
{
Thread.MemoryBarrier();
return _time;
}
set
{
_time = value;
Thread.MemoryBarrier();
}
}
该属性可以从不同的线程访问,因此我想确保它们始终获得最新版本,而不使用争用(lock
)。
编辑:
- 我有一组难以创建的项目,每个项目都有一个名为
CreationTime
的DateTime
属性,指示该项目的创建时间。它被初始化为DateTime.UtcNow
。 - 每次访问某个项目时,该属性都会更新为
DateTime.UtcNow
。 - 有一个线程,在线程计时器中及时执行,检查
if (DateTime.UtcNow + 1 hour) > > item.CreationTime
,如果为 true,则删除该项目。
我想确保当“删除线程”进入集合时,所有项目都有其最新的“上次访问”DateTime
,这样我就可以避免仅仅因为缓存保留而再次创建该项目几毫秒的值。 :D
As DateTime
cannot be declared as volatile
, is this right?
private DateTime _time;
public DateTime Time
{
get
{
Thread.MemoryBarrier();
return _time;
}
set
{
_time = value;
Thread.MemoryBarrier();
}
}
That property could be accessed from different threads, so I want to ensure they get always the latest version, without use contention (lock
).
EDIT:
- I have a collection of hard-to-create items, each one has a
DateTime
property namedCreationTime
, indicating when this item was created. It's initialized toDateTime.UtcNow
. - Every time a item is accessed, that property is updated to
DateTime.UtcNow
. - There is a thread, that executes in timely fashion in a threaded timer that checks
if (DateTime.UtcNow + 1 hour) > item.CreationTime
, if true it deletes the item.
I want to ensure that when the "deletion thread" comes into the collection, all the items have their latest "last access" DateTime
on it, so I can avoid create the item again just because a cache held the value for a couple of milliseconds. :D
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
恰恰。
但是,你还有另一种选择。将时间存储为 Int64 刻度计数,并使用
InterlockedExchange
进行设置。然后,线程可以使用 Int64 构造自己的DateTime
a> 构造函数,没有争用,也没有锁。编辑:
鉴于您提供了更多信息,现在更容易提供示例。
Precisely.
But, you have another option. Store the time as an Int64 tick count, and use
InterlockedExchange
to set. Threads can then construct their ownDateTime
using The Int64 constructor, giving you no contention and no locks.EDIT:
Given that you've provided more information, it's easier now to provide an example.
您的代码不是线程安全的,因为
DateTime
的分配不能保证是原子的。一般来说,32 位以下的整数赋值是原子的,但 64 位的整数则不必是原子的。您可能可以将 Interlocked.Exchange 与 DateTime 的刻度一起使用,因为它可以自动存储 Int64。
但如果您切换到刻度,您需要知道只有 62 位用于刻度,2 位用于类型。所以你不会失去那种。
即使你使 getter 和 setter 原子化并成为线程安全的,我也不确定这是否足够。由于获取器返回的时间和您实际使用所获得的时间之间的时间可能会发生变化。所以你的时间总是会过时。
Your code isn't thread-safe since the assignment of
DateTime
isn't guaranteed to be atomic. In general assignments of integers up to 32bits are atomic, but 64 needn't be atomic.You probably can use
Interlocked.Exchange
with the ticks of theDateTime
since that can atomically store an Int64.But if you switch to ticks you need to know that only 62 bits are used for the ticks, and 2 bits for the kind. So you don't lose the kind.
And even if you make the getter and setter atomic an threadsafe, I'm not sure if that's enough. Since the time can change between the time where your getter returns and the time you actually work with the time you got. So your time can always be outdated.
这是不可能的 - 您需要使用
lock
或Monitor
类来同步对该字段的访问。这是因为
DateTime
是一种值类型 - 一种结构。来自 MSDN - 易失性(C# 参考):
正如其他人提到的,您可以使用
Ticks
来跟踪时间。This is not possible - you will need to use
lock
or theMonitor
class to synchronize access to the field.This is because
DateTime
is a value type - a structure.From MSDN - volatile (C# Reference):
As others have mentioned, you can use
Ticks
to track time..NET Core 包含
不安全.As
方法,它允许对DateTime
变量执行易失性读/写,如下所示:用法:
这是一个 hack,因为它取决于
DateTime
类型永远由ulong
字段支持。根据具体情况,自行判断使用它是否合适/安全/谨慎。来自 源代码:
The .NET Core includes the
Unsafe.As
method, which allows to perform a volatile read/write on aDateTime
variable like this:Usage:
This is a hack, as it depends on the
DateTime
type being backed by aulong
field forever. Use your own judgement whether it's appropriate/safe/prudent to use it, in a case-by-case basis.From the source code of the
DateTime
struct:这行得通吗?
……
Would this work?
...
...