Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / whidbey / NetFxQFE / ndp / fx / src / Misc / WeakHashtable.cs / 1 / WeakHashtable.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.ComponentModel { using System; using System.Collections; using System.Security.Permissions; ////// This is a hashtable that stores object keys as weak references. /// It monitors memory usage and will periodically scavenge the /// hash table to clean out dead references. /// [HostProtection(SharedState = true)] internal sealed class WeakHashtable : Hashtable { private static IEqualityComparer _comparer = new WeakKeyComparer(); private long _lastGlobalMem; private int _lastHashCount; internal WeakHashtable() : base(_comparer) { } ////// Override of clear that performs a scavenge. /// public override void Clear() { base.Clear(); } ////// Override of remove that performs a scavenge. /// public override void Remove(object key) { base.Remove(key); } ////// Override of Item that wraps a weak reference around the /// key and performs a scavenge. /// public void SetWeak(object key, object value) { ScavengeKeys(); this[new EqualityWeakReference(key)] = value; } ////// This method checks to see if it is necessary to /// scavenge keys, and if it is it performs a scan /// of all keys to see which ones are no longer valid. /// To determine if we need to scavenge keys we need to /// try to track the current GC memory. Our rule of /// thumb is that if GC memory is decreasing and our /// key count is constant we need to scavenge. We /// will need to see if this is too often for extreme /// use cases like the CompactFramework (they add /// custom type data for every object at design time). /// private void ScavengeKeys() { int hashCount = Count; if (hashCount == 0) { return; } if (_lastHashCount == 0) { _lastHashCount = hashCount; return; } long globalMem = GC.GetTotalMemory(false); if (_lastGlobalMem == 0) { _lastGlobalMem = globalMem; return; } float memDelta = (float)(globalMem - _lastGlobalMem) / (float)_lastGlobalMem; float hashDelta = (float)(hashCount - _lastHashCount) / (float)_lastHashCount; if (memDelta < 0 && hashDelta >= 0) { // Perform a scavenge through our keys, looking // for dead references. // ArrayList cleanupList = null; foreach(object o in Keys) { WeakReference wr = o as WeakReference; if (wr != null && !wr.IsAlive) { if (cleanupList == null) { cleanupList = new ArrayList(); } cleanupList.Add(wr); } } if (cleanupList != null) { foreach(object o in cleanupList) { Remove(o); } } } _lastGlobalMem = globalMem; _lastHashCount = hashCount; } private class WeakKeyComparer : IEqualityComparer { bool IEqualityComparer.Equals(Object x, Object y) { if (x == null) { return y == null; } if (y != null && x.GetHashCode() == y.GetHashCode()) { WeakReference wX = x as WeakReference; WeakReference wY = y as WeakReference; if (wX != null) { if (!wX.IsAlive) { return false; } x = wX.Target; } if (wY != null) { if (!wY.IsAlive) { return false; } y = wY.Target; } return object.ReferenceEquals(x, y); } return false; } int IEqualityComparer.GetHashCode (Object obj) { return obj.GetHashCode(); } } ////// A subclass of WeakReference that overrides GetHashCode and /// Equals so that the weak reference returns the same equality /// semantics as the object it wraps. This will always return /// the object's hash code and will return True for a Equals /// comparison of the object it is wrapping. If the object /// it is wrapping has finalized, Equals always returns false. /// private sealed class EqualityWeakReference : WeakReference { private int _hashCode; internal EqualityWeakReference(object o) : base(o) { _hashCode = o.GetHashCode(); } public override bool Equals(object o) { if (o == null) { return false; } if (o.GetHashCode() != _hashCode) { return false; } if (o == this || (IsAlive && object.ReferenceEquals(o, Target))) { return true; } return false; } public override int GetHashCode() { return _hashCode; } } /* The folowing code has been removed to prevent FXCOP violation It is left here incase it needs to be resurected ////// Override of add that wraps a weak reference around the /// key and performs a scavenge. /// public void AddWeak(object key, object value) { ScavengeKeys(); base.Add(new EqualityWeakReference(key), value); } */ } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.ComponentModel { using System; using System.Collections; using System.Security.Permissions; ////// This is a hashtable that stores object keys as weak references. /// It monitors memory usage and will periodically scavenge the /// hash table to clean out dead references. /// [HostProtection(SharedState = true)] internal sealed class WeakHashtable : Hashtable { private static IEqualityComparer _comparer = new WeakKeyComparer(); private long _lastGlobalMem; private int _lastHashCount; internal WeakHashtable() : base(_comparer) { } ////// Override of clear that performs a scavenge. /// public override void Clear() { base.Clear(); } ////// Override of remove that performs a scavenge. /// public override void Remove(object key) { base.Remove(key); } ////// Override of Item that wraps a weak reference around the /// key and performs a scavenge. /// public void SetWeak(object key, object value) { ScavengeKeys(); this[new EqualityWeakReference(key)] = value; } ////// This method checks to see if it is necessary to /// scavenge keys, and if it is it performs a scan /// of all keys to see which ones are no longer valid. /// To determine if we need to scavenge keys we need to /// try to track the current GC memory. Our rule of /// thumb is that if GC memory is decreasing and our /// key count is constant we need to scavenge. We /// will need to see if this is too often for extreme /// use cases like the CompactFramework (they add /// custom type data for every object at design time). /// private void ScavengeKeys() { int hashCount = Count; if (hashCount == 0) { return; } if (_lastHashCount == 0) { _lastHashCount = hashCount; return; } long globalMem = GC.GetTotalMemory(false); if (_lastGlobalMem == 0) { _lastGlobalMem = globalMem; return; } float memDelta = (float)(globalMem - _lastGlobalMem) / (float)_lastGlobalMem; float hashDelta = (float)(hashCount - _lastHashCount) / (float)_lastHashCount; if (memDelta < 0 && hashDelta >= 0) { // Perform a scavenge through our keys, looking // for dead references. // ArrayList cleanupList = null; foreach(object o in Keys) { WeakReference wr = o as WeakReference; if (wr != null && !wr.IsAlive) { if (cleanupList == null) { cleanupList = new ArrayList(); } cleanupList.Add(wr); } } if (cleanupList != null) { foreach(object o in cleanupList) { Remove(o); } } } _lastGlobalMem = globalMem; _lastHashCount = hashCount; } private class WeakKeyComparer : IEqualityComparer { bool IEqualityComparer.Equals(Object x, Object y) { if (x == null) { return y == null; } if (y != null && x.GetHashCode() == y.GetHashCode()) { WeakReference wX = x as WeakReference; WeakReference wY = y as WeakReference; if (wX != null) { if (!wX.IsAlive) { return false; } x = wX.Target; } if (wY != null) { if (!wY.IsAlive) { return false; } y = wY.Target; } return object.ReferenceEquals(x, y); } return false; } int IEqualityComparer.GetHashCode (Object obj) { return obj.GetHashCode(); } } ////// A subclass of WeakReference that overrides GetHashCode and /// Equals so that the weak reference returns the same equality /// semantics as the object it wraps. This will always return /// the object's hash code and will return True for a Equals /// comparison of the object it is wrapping. If the object /// it is wrapping has finalized, Equals always returns false. /// private sealed class EqualityWeakReference : WeakReference { private int _hashCode; internal EqualityWeakReference(object o) : base(o) { _hashCode = o.GetHashCode(); } public override bool Equals(object o) { if (o == null) { return false; } if (o.GetHashCode() != _hashCode) { return false; } if (o == this || (IsAlive && object.ReferenceEquals(o, Target))) { return true; } return false; } public override int GetHashCode() { return _hashCode; } } /* The folowing code has been removed to prevent FXCOP violation It is left here incase it needs to be resurected ////// Override of add that wraps a weak reference around the /// key and performs a scavenge. /// public void AddWeak(object key, object value) { ScavengeKeys(); base.Add(new EqualityWeakReference(key), value); } */ } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- EnumValAlphaComparer.cs
- FileDialog_Vista_Interop.cs
- HandlerWithFactory.cs
- PagePropertiesChangingEventArgs.cs
- ImageList.cs
- BlurBitmapEffect.cs
- ConfigurationValues.cs
- WebPartConnectionsEventArgs.cs
- StringHelper.cs
- IndependentlyAnimatedPropertyMetadata.cs
- NextPreviousPagerField.cs
- Screen.cs
- SwitchAttribute.cs
- PropertyValueChangedEvent.cs
- LowerCaseStringConverter.cs
- LeafCellTreeNode.cs
- SQlBooleanStorage.cs
- CursorInteropHelper.cs
- PerfService.cs
- metadatamappinghashervisitor.hashsourcebuilder.cs
- HwndKeyboardInputProvider.cs
- WindowsIdentity.cs
- WebConfigurationFileMap.cs
- ParameterReplacerVisitor.cs
- Rotation3DAnimation.cs
- securitycriticaldata.cs
- SafeRegistryHandle.cs
- ClientSession.cs
- SqlRemoveConstantOrderBy.cs
- ToolStripItemTextRenderEventArgs.cs
- HashAlgorithm.cs
- GifBitmapDecoder.cs
- DataGridViewLinkColumn.cs
- DataGridViewComboBoxCell.cs
- DataServiceQueryException.cs
- DefaultExpression.cs
- Section.cs
- MemoryFailPoint.cs
- ReferenceAssemblyAttribute.cs
- KoreanCalendar.cs
- SpeechSeg.cs
- DiffuseMaterial.cs
- RightNameExpirationInfoPair.cs
- EntityTypeBase.cs
- CacheSection.cs
- ComPlusDiagnosticTraceSchemas.cs
- PageHandlerFactory.cs
- DesignerAutoFormatStyle.cs
- WindowHideOrCloseTracker.cs
- RotateTransform3D.cs
- DesignTimeData.cs
- HelpInfo.cs
- VScrollBar.cs
- InternalBufferOverflowException.cs
- WebDescriptionAttribute.cs
- FieldValue.cs
- CollectionChangeEventArgs.cs
- BitmapEffectInput.cs
- DefaultAsyncDataDispatcher.cs
- ClientSettingsStore.cs
- WaitHandleCannotBeOpenedException.cs
- EmptyEnumerator.cs
- ContextBase.cs
- EntityContainerEntitySetDefiningQuery.cs
- ClosableStream.cs
- GenerateHelper.cs
- ControlPropertyNameConverter.cs
- QilReference.cs
- DesignerVerb.cs
- XsltFunctions.cs
- StylusButtonCollection.cs
- DetailsViewUpdatedEventArgs.cs
- SmtpException.cs
- DataColumnMappingCollection.cs
- InvalidateEvent.cs
- CircleHotSpot.cs
- RoleGroup.cs
- SafeRegistryHandle.cs
- BindUriHelper.cs
- ProviderConnectionPointCollection.cs
- PenThreadWorker.cs
- DbXmlEnabledProviderManifest.cs
- SocketElement.cs
- CollectionDataContract.cs
- Console.cs
- FieldBuilder.cs
- SQLByteStorage.cs
- linebase.cs
- CompilationUnit.cs
- SafeRightsManagementQueryHandle.cs
- RightsManagementErrorHandler.cs
- EmptyControlCollection.cs
- XmlSerializerFaultFormatter.cs
- Win32.cs
- Sorting.cs
- UnauthorizedWebPart.cs
- Statements.cs
- HyperLinkField.cs
- CallTemplateAction.cs
- SharedUtils.cs