如果DateTime.Now不是';It’还不够好
本文关键字:It 不够 DateTime Now 不是 如果 | 更新日期: 2023-09-27 18:21:12
好的,这就是问题所在。我们将CQRS与Event Sourcing一起使用,并使用聚合实例的每个提交序列的事件流。每个流都有其各自的创建日期,但问题是,所有这些都发生得太快了,这意味着一些聚合事件流(注册、通知等)的日期完全相同。因此,当我们必须重播事件时,按创建日期对流进行排序是不可行的,因为有一些事件流在时间上是依赖的,但它们发生得太快了,看起来像是并行发生的(这意味着我们使用了DateTime.UtcNow,日期等于纳秒)。
对于那些不知道什么是CQRS或事件来源的人
假设您有一个资源列表,并且每个项目都有其创建日期。了解列表中项目的创建顺序至关重要。请记住,有多个线程在列表中创建和添加项目。问题是,当一个线程必须在列表中创建并添加两个项目时,它们的创建日期匹配,你无法正确地按日期排序。顺便说一句,电脑在我的电脑上很重要DateTime。现在不等于DateTime。在服务器上是这样。实际上,在同事的电脑上添加了25000次DateTime。对于列表,列表的第一个和最后一个元素等于纳秒(完全匹配)
在事件源中,典型的保证只是在单个流中对事件进行排序,例如一个聚合。无论如何,这是您的交易担保。为什么不使用一个整数来跟踪流中每个事件的序列呢?您的聚合可以生成它,因为它一直在跟踪所有事件。
如果你想跨流排序,你必须集中生成序列号(使用表示的耦合),或者接受多个流的多次读取不会总是返回相同顺序的事件,只是一个流中的事件应该被排序。
您可以通过调用Windows API的QueryPerformanceCounter()
来获得一个准确的数字,您可以将其用作时间戳,应该以非常高的分辨率在线程之间为您提供一致的值。
当然,这只会为您提供与一台特定计算机相关的值;如果你想比较在两台不同的计算机上创建的时间戳,就不能使用它。
但是,请注意(来自Windows API文档):
在多处理器计算机上,调用哪个处理器应该无关紧要。然而,由于基本输入/输出系统(BIOS)或硬件抽象层(HAL)中的错误,您可能会在不同的处理器上获得不同的结果。
(我自己在任何硬件上都没有遇到过上述错误。)
您可以通过C#访问性能计数器,如下所示:
public long PerformanceCounter()
{
long result;
QueryPerformanceCounter(out result);
return result;
}
[DllImport("kernel32.dll", SetLastError=true)]
static extern bool QueryPerformanceCounter(out long lpPerformanceCount);