我有一些只讀數據,我想要初始化,然後以線程安全方式定期重新初始化。對於初始化,我拉入了Joe Duffy的LazyInit and LazyInitOnceOnly structs as detailed in his blog,它使用了Double-Checked鎖定模式。所以我目前執行的吸氣劑只是環繞他LazyInitOnceOnly.Value
財產,給定的時間進行檢查增值空間:線程安全共享對象到期和重新初始化
因此,代碼如下:
public class MyData {
public DateTime TimeStamp { get; set; }
//actual shared data ommitted
public MyData() { TimeStamp = DateTime.Now; }
}
public SharedDataContainer
{
//data to be initialised thread-safe, and shared.
//assume delegate passed on construction simply 'new's the object,
private LazyInitOnceOnly<MyData> _sharedDataInit;
//receives the result from the _sharedDataInit.Value property
private MyData _sharedData;
//time-out and reinitialise after 24 hours
private TimeSpan _timeOut = new TimeSpan(24,0,0);
public MyData SharedData
{
get{
//slight adaptation of the use of the LazyInitOnceOnly struct -
//because we want to replace _sharedData later after an expiry time out.
if(_sharedData == null)
_sharedData = _sharedDataInit.Value;
//need best ideas for this bit:
if((DateTime.Now - _sharedData.TimeStamp) > _timeOut)
{
ReInitialise();
}
return _sharedData;
}
}
}
當數據被確立爲擺脫日期時,應該返回舊數據,但新數據應在單獨的線程上準備好,並在準備就緒時進行交換 - 以免阻止調用者。從數據中的所有後續讀取應該返回舊值直到更新。
所以我認爲在ReInitialise()
方法排隊這樣的新線程:
() => {
//assume constructor pulls in all the data and sets timestamp
_sharedData = new MyData();
}
的_sharedData覆蓋在該線程將原子發生,所以這是很好。但是通過這段代碼,直到重建完成,所有後續讀取都會嘗試並觸發線程重建 - 因爲它們正在讀取舊的_sharedData的TimeStamp屬性。
確保只觸發一次重建的最佳方法是什麼?
所以你希望重建發生在一個新的,衍生出來的後臺工作線程和主客戶線程上,以便直接返回**舊**數據(即使getter知道它是舊的)直到在後臺線程上重建做完了??只是檢查這裏的要求.... – martinr 2010-01-18 12:45:39
是的,沒錯 - 對不起,我在我的問題中有點鬆了一口氣!這是我的一個詛咒。 – 2010-01-18 12:51:44
已更新文本,使其更清晰一點 - 謝謝;) – 2010-01-18 12:55:42