您是否考慮過使用System.Web.Caching
而不是自己動手?
http://www.hanselman.com/blog/UsingTheASPNETCacheOutsideOfASPNET.aspx
編輯
遠高於不宜加那麼多的開銷系統,但看看這個。
關於下面的代碼的一些健康警告。
- 它是不完整的......見底部的
throw new NotImplementedException()
s。我會嘗試一段時間回來,因爲這是一個有趣的謎題。
- 您可能想要過期完成&已覆蓋添加方法以向構造的值提供不同的值
- 我只測試過它在控制檯應用程序中的最低限度。請參閱測試代碼
- 它還需要TKey & TValue Collections的一些工作,因爲他們會盲目地返回內部字典集合的完整內容,而沒有任何到期檢查......如果您不需要特別粒度的到期。您可以將system.timer添加到定期遍歷整個集合並刪除過期條目的類中。
- 如果你看看BCL詞典的定義,你會發現它實現了許多其他接口的地獄,所以根據你的需求,你可能也想實現這些接口。
IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IDictionary, ICollection, IEnumerable, ISerializable, IDeserializationCallback
測試代碼
TimeSpan t = new TimeSpan(0,0,5); //5 Second Expiry
ExpiringDictionary<int, string> dictionary
= new ExpiringDictionary<int,string>(t);
dictionary.Add(1, "Alice");
dictionary.Add(2, "Bob");
dictionary.Add(3, "Charlie");
//dictionary.Add(1, "Alice"); //<<this will throw a exception as normal...
System.Threading.Thread.Sleep(6000);
dictionary.Add(1, "Alice"); //<< this however should work fine as 6 seconds have passed
實施
public class ExpiringDictionary<TKey, TValue> : IDictionary<TKey, TValue>
{
private class ExpiringValueHolder<T> {
public T Value { get; set; }
public DateTime Expiry { get; private set; }
public ExpiringValueHolder(T value, TimeSpan expiresAfter)
{
Value = value;
Expiry = DateTime.Now.Add(expiresAfter);
}
public override string ToString() { return Value.ToString(); }
public override int GetHashCode() { return Value.GetHashCode(); }
};
private Dictionary<TKey, ExpiringValueHolder<TValue>> innerDictionary;
private TimeSpan expiryTimeSpan;
private void DestoryExpiredItems(TKey key)
{
if (innerDictionary.ContainsKey(key))
{
var value = innerDictionary[key];
if (value.Expiry < System.DateTime.Now)
{
//Expired, nuke it in the background and continue
innerDictionary.Remove(key);
}
}
}
public ExpiringDictionary(TimeSpan expiresAfter)
{
expiryTimeSpan = expiresAfter;
innerDictionary = new Dictionary<TKey, ExpiringValueHolder<TValue>>();
}
public void Add(TKey key, TValue value)
{
DestoryExpiredItems(key);
innerDictionary.Add(key, new ExpiringValueHolder<TValue>(value, expiryTimeSpan));
}
public bool ContainsKey(TKey key)
{
DestoryExpiredItems(key);
return innerDictionary.ContainsKey(key);
}
public bool Remove(TKey key)
{
DestoryExpiredItems(key);
return innerDictionary.Remove(key);
}
public ICollection<TKey> Keys
{
get { return innerDictionary.Keys; }
}
public bool TryGetValue(TKey key, out TValue value)
{
bool returnval = false;
DestoryExpiredItems(key);
if (innerDictionary.ContainsKey(key))
{
value = innerDictionary[key].Value;
returnval = true;
} else { value = default(TValue);}
return returnval;
}
public ICollection<TValue> Values
{
get { return innerDictionary.Values.Select(vals => vals.Value).ToList(); }
}
public TValue this[TKey key]
{
get
{
DestoryExpiredItems(key);
return innerDictionary[key].Value;
}
set
{
DestoryExpiredItems(key);
innerDictionary[key] = new ExpiringValueHolder<TValue>(value, expiryTimeSpan);
}
}
public void Add(KeyValuePair<TKey, TValue> item)
{
DestoryExpiredItems(item.Key);
innerDictionary.Add(item.Key, new ExpiringValueHolder<TValue>(item.Value, expiryTimeSpan));
}
public void Clear()
{
innerDictionary.Clear();
}
public int Count
{
get { return innerDictionary.Count; }
}
public bool IsReadOnly
{
get { return false; }
}
public bool Contains(KeyValuePair<TKey, TValue> item)
{
throw new NotImplementedException();
}
public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
{
throw new NotImplementedException();
}
public bool Remove(KeyValuePair<TKey, TValue> item)
{
throw new NotImplementedException();
}
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
{
throw new NotImplementedException();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
}
這是個好主意(答案的第一部分)。我的問題是在插入方面,但可以應用這個想法。我不同意使用任何額外的線程。 – Xaqron 2011-05-14 19:31:28
你很可能是對的,hastable沒有時間在hastable中找到物品,因此刪除物品對速度沒有幫助。但額外的線程將無用的使用CPU。線程唯一幫助的是如果大量添加的項目永遠不會被處理,它將移除它們並最大限度地減少內存消耗 – 2011-05-14 19:53:17
+1好點。它可能是一個計時器線程。 – Xaqron 2011-05-14 20:16:04