2010-02-16 30 views
3

在我的.net域對象中我正在跟蹤每個狀態轉換。這是通過將狀態設置爲狀態歷史記錄集合來完成的。所以稍後,可以看到一個desc的有序列表,找出其中的狀態在更改了什麼時間。.Net DateTime精度

所以有這樣的方法:

private void SetState(RequestState state) 
{ 
    var stateHistoryItem = new RequestStateHistoryItem(state, this); 

    stateHistoryItems.Add(stateHistoryItem); 
} 

當一個新RequestStateHistoryItem被實例化,當前的日期將自動分配。像這樣:

protected IdentificationRequestStateHistoryItem() 
{ 
    timestamp = EntityTimestamp.New(); 
} 

EntityTimestamp對象是含有此時,相應的用戶和創建和改變日期的對象。

當列出的狀態歷史,我做了降序使用LINQ:

public virtual IEnumerable<RequestStateHistoryItem> StateHistoryItems 
{ 
    get { return stateHistoryItems.OrderByDescending(s => s.Timestamp.CreatedOn.Ticks); } 
} 

現在,當一個新的Request被實例化的第一狀態Received是在構造函數SetState(RequestState.Received)設置。然後,沒有任何延遲並取決於某些條件,設置新狀態Started。經過一段時間(數據庫操作)後,設置了狀態Finished

現在執行降序排序時,Received總是在Started狀態之後。當我慢慢地調試時,或者在將狀態設置爲Started之前放置System.Threading.Thread.Sleep(1000)時,排序工作。 如果沒有,如上所述,Started狀態的CreatedOn是OLDER然後Received CreatedOn date ?!

TimeOfDay {17:04:42.9430318} FINSHED 
Ticks 634019366829430318 

TimeOfDay {17:04:39.5376207} RECEICED 
Ticks 634019366795376207 

TimeOfDay {17:04:39.5367815} STARTED 
Ticks 634019366795367815 

這怎麼可能?我會理解,如果收到的和開始日期完全相同,但我不明白它如何能在另一個之前?

我已經嘗試new DateTimePrecise().Now,(請參閱DateTimePrecise class)我發現在另一個問題。同樣的結果。

任何人都知道這可能是什麼?

更新

public virtual bool Finish() 
{ 
    // when I put the SetState(State.Received) from the constructor into here, the timestamp of finish still is BEFORE received 
    SetState(IdentificationRequestState.Received); 
    SetState(IdentificationRequestState.Finished);   

    // when I put the SetState(State.Received) after Finished, then the Received timestamp is BEFORE Finished 
    SetState(IdentificationRequestState.Finished);   
    SetState(IdentificationRequestState.Received); 

    var match = ... 

    if (match != null) 
    { 
     ... 
    } 
    else 
    { 
     ... 
    } 
} 
+0

你在多線程環境中運行?如果接收和啓動狀態是由不同線程請求的,這可以解釋您看到的差異。 – 2010-02-16 16:42:38

回答

0

您是否嘗試過通過同樣的方法設置兩個ReceivedStarted時間戳(即移動Received戳出來的構造,並通過屬性或方法將其設置到如何Started匹配狀態是否設置?)。

我知道它並不能解釋爲什麼,但構造函數在運行時有點特殊。 .NET構造函數被設計爲儘可能快地執行,所以我不會感到驚訝的是,注重性能有一些副作用。

2

DateTime.Now不準確到毫秒。它只在更大的時間間隔更新,例如30或15毫秒(這正是Window內部時鐘工作的方式,IIRC)。

System.Diagnostics。秒錶是更準確的方式來測量時間差異。它也沒有UTC本地時間轉換等開銷。DateTimePrecise類使用DateTime和秒錶的組合來提供比DateTime.Now更準確的時間。

+0

的確,有更準確的方法來記錄時間比DateTime.Now,但這不是問題在這裏。看到我的答案。 – Joe 2010-02-16 17:56:16

2

您正在檢索時間戳之前您將其添加到您的收藏。

檢索它並將其添加到集合中的延遲是可變的 - 例如,在獲取時間戳和添加到集合之前,您的線程可能會被調度程序預先佔用。

如果你想嚴格的排序,你需要使用同步,有點像每次你實例化一個歷史項時間如下:

lock(syncLock) 
{ 
    // Timestamp is generated here... 
    var stateHistoryItem = new RequestStateHistoryItem(state, this); 
    // ... but an indeterminate time can pass before ... 
    ... 
    // ... it's added to the collection here. 
    stateHistoryItems.Add(stateHistoryItem); 
} 
+0

我嘗試過,但它沒有幫助...但無論如何感謝 – Chris 2010-02-16 22:06:24