private bool disposedValue = false; // To detect redundant calls protected virtual void Dispose(bool disposing) { if (!disposedValue) { if (disposing) { _stopEvent.Set(); _scanThread.Join((int)(_scanInterval.TotalMilliseconds * 100)); //x3 is enough... x100 is safe and of same effect as x3 _stopEvent.Dispose(); List <AutoTimeoutObject> expired = new List <AutoTimeoutObject>(); foreach (var aot in _con.Values) { expired.Add(aot); } foreach (var ee in expired) { AutoTimeoutObject aot = null; _con.TryRemove(ee.Id, out aot); ee.Dispose(); } } // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below. // TODO: set large fields to null. disposedValue = true; } }
public Guid Add(object obj, bool longLived = false, TimeSpan?life = null, Action <object> disposeAction = null) { AutoTimeoutObject ato = new AutoTimeoutObject { Id = Guid.NewGuid(), Object = obj, DisposeAction = disposeAction, Age = TimeSpan.FromMilliseconds(0), //in sec Life = life ?? _defaultLife, //in sec LongLived = longLived }; _con.TryAdd(ato.Id, ato); return(ato.Id); }
public T Delete <T>(Guid id) { AutoTimeoutObject aot = null; AutoTimeoutObject res = null; _con.TryRemove(id, out aot); if (null != aot) { lock (aot) { if (aot.LongLived || aot.Age < aot.Life) { aot.Age = TimeSpan.FromMilliseconds(0); res = aot; } } } return((T)(res?.Object)); }
private void Scan() { //object state // - not expired, hence must be in container // - expired, but still in container // - expired, and removed from container for (;;) { bool stop = _stopEvent.WaitOne(_scanInterval); if (stop) { break; } List <AutoTimeoutObject> expired = new List <AutoTimeoutObject>(); foreach (var aot in _con.Values) { bool isExpired = false; lock (aot) { aot.Age += _scanInterval; isExpired = !aot.LongLived && (aot.Age >= aot.Life); } if (isExpired) { expired.Add(aot); } } foreach (var ee in expired) { AutoTimeoutObject aot = null; _con.TryRemove(ee.Id, out aot); ee.Dispose(); } } }