using System; using System.Threading; using Microsoft.Ccr.Core; namespace Roblox.Common { public class RefreshAhead : IDisposable { private DateTime _LastRefresh = DateTime.MinValue; private readonly Timer _RefreshTimer = null; private T _Value = default(T); public TimeSpan IntervalSinceRefresh { get { return DateTime.Now.Subtract(_LastRefresh); } } public T Value { get { return _Value; } } private RefreshAhead(T initialValue, TimeSpan refreshInterval, Func refreshDelegate) { int refreshIntervalInMilliseconds = (int)refreshInterval.TotalMilliseconds; _Value = initialValue; _LastRefresh = DateTime.Now; _RefreshTimer = new Timer( (stateInfo) => Refresh(refreshDelegate), null, refreshIntervalInMilliseconds, refreshIntervalInMilliseconds ); } private RefreshAhead(T initialValue, TimeSpan refreshInterval, Action> refreshDelegate) { int refreshIntervalInMilliseconds = (int)refreshInterval.TotalMilliseconds; _Value = initialValue; _LastRefresh = DateTime.Now; _RefreshTimer = new Timer( (stateInfo) => Refresh(refreshDelegate), null, refreshIntervalInMilliseconds, refreshIntervalInMilliseconds ); } public RefreshAhead(TimeSpan refreshInterval, Func refreshDelegate) { int refreshIntervalInMilliseconds = (int)refreshInterval.TotalMilliseconds; _RefreshTimer = new Timer( (stateInfo) => Refresh(refreshDelegate), null, refreshIntervalInMilliseconds, refreshIntervalInMilliseconds ); } private void Refresh(Func refreshDelegate) { try { _Value = refreshDelegate(); _LastRefresh = DateTime.Now; } catch (ThreadAbortException) { throw; } catch (Exception ex) { ExceptionHandler.LogException(ex); } } private void Refresh(Action> refreshDelegate) { try { var valueResult = new PortSet(); refreshDelegate(valueResult); CcrService.Singleton.Choice( valueResult, (value) => { _Value = value; _LastRefresh = DateTime.Now; } ); } catch (ThreadAbortException) { throw; } catch (Exception ex) { ExceptionHandler.LogException(ex); } } public static RefreshAhead ConstructAndPopulate(TimeSpan refreshInterval, Func refreshDelegate) { T value = refreshDelegate(); var refreshAhead = new RefreshAhead(value, refreshInterval, refreshDelegate); return refreshAhead; } public static void ConstructAndPopulate(TimeSpan refreshInterval, Action> refreshDelegate, PortSet, Exception> result) { var valueResult = new PortSet(); refreshDelegate(valueResult); CcrService.Singleton.Choice( valueResult, (value) => { var refreshAhead = new RefreshAhead(value, refreshInterval, refreshDelegate); result.Post(refreshAhead); }, (ex) => result.Post(ex) ); } #region IDisposable Members public void Dispose() { if (_RefreshTimer != null) _RefreshTimer.Dispose(); } #endregion } }