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
- InvalidDataException.cs
- ToolbarAUtomationPeer.cs
- WebHttpElement.cs
- ContentType.cs
- Variable.cs
- DataListDesigner.cs
- AudienceUriMode.cs
- Button.cs
- SetterBase.cs
- ColumnMap.cs
- NativeMethods.cs
- WindowsSolidBrush.cs
- TrackBar.cs
- OdbcDataAdapter.cs
- EDesignUtil.cs
- OutputCacheSection.cs
- XmlFormatExtensionPrefixAttribute.cs
- RecordManager.cs
- VisualStyleElement.cs
- AccessKeyManager.cs
- BoolExpressionVisitors.cs
- MetadataArtifactLoaderComposite.cs
- QueryStringParameter.cs
- ProvidePropertyAttribute.cs
- JsonDeserializer.cs
- QueryPageSettingsEventArgs.cs
- FtpRequestCacheValidator.cs
- MatrixUtil.cs
- PersonalizationProvider.cs
- XmlChildNodes.cs
- TextAdaptor.cs
- AutomationProperties.cs
- XPathNodeHelper.cs
- BlobPersonalizationState.cs
- ClassicBorderDecorator.cs
- DaylightTime.cs
- SQLBinary.cs
- ELinqQueryState.cs
- HideDisabledControlAdapter.cs
- DataServices.cs
- UndoEngine.cs
- SplitterPanel.cs
- FunctionNode.cs
- SystemIdentity.cs
- DemultiplexingClientMessageFormatter.cs
- ColumnProvider.cs
- DbDataRecord.cs
- KeyInterop.cs
- WebPartHeaderCloseVerb.cs
- ControlOperationInvoker.cs
- PowerModeChangedEventArgs.cs
- AvTraceFormat.cs
- TableItemPatternIdentifiers.cs
- BuildDependencySet.cs
- SqlWriter.cs
- ImportCatalogPart.cs
- PropertyGroupDescription.cs
- CodeExpressionCollection.cs
- ToolStripTemplateNode.cs
- VisualStyleRenderer.cs
- PresentationSource.cs
- TableHeaderCell.cs
- DependencyObject.cs
- TransactionState.cs
- ContentType.cs
- AttributeTableBuilder.cs
- DataBindingExpressionBuilder.cs
- HtmlGenericControl.cs
- MessageSecurityTokenVersion.cs
- ExcCanonicalXml.cs
- Button.cs
- EmptyEnumerable.cs
- TimeSpanConverter.cs
- LambdaReference.cs
- FormsAuthenticationEventArgs.cs
- ColorContextHelper.cs
- SqlMethods.cs
- SimpleApplicationHost.cs
- TrackingProfileCache.cs
- DataBindingCollectionEditor.cs
- SpellerStatusTable.cs
- BaseCollection.cs
- X509CertificateChain.cs
- PermissionRequestEvidence.cs
- WorkflowMarkupSerializationManager.cs
- SecureConversationSecurityTokenParameters.cs
- COM2ExtendedBrowsingHandler.cs
- EmbeddedMailObjectsCollection.cs
- ZipIOLocalFileHeader.cs
- ReadOnlyCollectionBase.cs
- TransportSecurityHelpers.cs
- AttachedPropertyBrowsableAttribute.cs
- PlatformNotSupportedException.cs
- VisualTreeUtils.cs
- HttpProfileBase.cs
- AppSettingsExpressionEditor.cs
- PropertyRef.cs
- InputManager.cs
- IntranetCredentialPolicy.cs
- ImpersonateTokenRef.cs