nbsp;
有了这个数据结构我们就可以将数据实现两份存储。再利用一些读写策略就可以实现上面我们讲的缓存方式。转
整个的缓存我们使用如下缓存类来控制:
/* * http://www.cnblogs.com/chsword/ * chsword * Date: 2009-3-31 * Time: 17:00 * */ using System; using System.Collections; using System.Collections.Generic; using System.Threading; namespace CHCache { /// <summary> /// 双存储的类 /// </summary> public class DictionaryCache : IEnumerable { /// <summary> /// 在此缓存构造时初始化字典对象 /// </summary> public DictionaryCache() { Store = new Dictionary<string, Medium>(); } public void Add(string key,Func<object> func) { if (Store.ContainsKey(key)) {//修改,如果已经存在,再次添加时则采用其它线程 var elem = Store[key]; if (elem.IsUpdating)return; //正在写入未命中 var th = new ThreadHelper(elem, func);//ThreadHelper将在下文提及,是向其它线程传参用的 var td = new Thread(th.Doit); td.Start(); } else {//首次添加时可能也要读取,所以要本线程执行 Console.WriteLine("Begin first write"); Store.Add(key, new Medium {IsPrimary = true, Primary = func()}); Console.WriteLine("End first write"); }
} /// <summary> /// 读取时所用的索引 /// </summary> /// <param name="key"></param> /// <returns></returns> public object this[string key] { get { if (!Store.ContainsKey(key))return null; var elem = Store[key]; if (elem.IsUpdated) {//如果其它线程更新完毕,则将主次转置 elem.IsUpdated = false; elem.IsPrimary = !elem.IsPrimary; } var ret = elem.IsPrimary ? elem.Primary : elem.Secondary; var b = elem.IsPrimary ? " from 1" : " form 2"; return ret + b; } } Dictionary<string, Medium> Store { get; set; } public IEnumerator GetEnumerator() { return ((IEnumerable)Store).GetEnumerator(); } }
|