using System; using System.Collections.Generic; using System.Threading; using MarketData; using MarketData.Utils; using MarketData.DataAccess; namespace PortfolioManager.Cache { public class SymbolCache : IDisposable { private List symbolCache=new List(); private Object thisLock=new Object(); private Thread cacheMonitorThread=null; private volatile bool threadRun=true; private int cacheRefreshAfter=60000; // Invalidate cache after private static SymbolCache symbolCacheInstance=null; private SymbolCache() { cacheMonitorThread=new Thread(new ThreadStart(ThreadProc)); cacheMonitorThread.Start(); } public static SymbolCache GetInstance() { lock(typeof(SymbolCache)) { if(null==symbolCacheInstance) symbolCacheInstance=new SymbolCache(); return symbolCacheInstance; } } public void Clear() { lock(thisLock) { symbolCache=new List(); } } public void Dispose() { lock(thisLock) { if(null==symbolCacheInstance || false==threadRun)return; threadRun=false; symbolCacheInstance=null; } if(null!=cacheMonitorThread) { MDTrace.WriteLine(LogLevel.DEBUG,String.Format("[SymbolCache:Dispose]Thread state is {0}. Joining main thread...",Utility.ThreadStateToString(cacheMonitorThread))); cacheMonitorThread.Join(5000); cacheMonitorThread=null; MDTrace.WriteLine(LogLevel.DEBUG,"[SymbolCache:Dispose] End."); } } public List GetSymbols() { lock(thisLock) { if(symbolCache.Count>0)return new List(symbolCache); } List symbols = PricingDA.GetSymbols(); lock(thisLock) { if(symbolCache.Count>0)return new List(symbolCache); symbolCache=new List(symbols); return new List(symbols); } } private void ThreadProc() { int quantums=0; int quantumInterval=1000; while(threadRun) { Thread.Sleep(quantumInterval); if(!threadRun)break; quantums+=quantumInterval; if(quantums>cacheRefreshAfter) { quantums=0; List symbols = PricingDA.GetSymbols(); lock(thisLock) { symbolCache=new List(symbols); } } } } } }