Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx40 / Tools / System.Activities.Presentation / System / Activities / Presentation / Model / WeakKeyDictionary.cs / 1305376 / WeakKeyDictionary.cs
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//---------------------------------------------------------------
namespace System.Activities.Presentation.Model
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Text;
using System.Runtime.InteropServices;
internal class WeakKeyDictionary : IDictionary
{
private Dictionary _internalDictionary;
private object _[....] = new object();
private bool _finalized;
public WeakKeyDictionary()
{
_internalDictionary = new Dictionary(new WeakComparer());
}
public WeakKeyDictionary(int capacity)
{
_internalDictionary = new Dictionary(capacity, new WeakComparer());
}
public WeakKeyDictionary(IEqualityComparer comparer)
{
_internalDictionary = new Dictionary(new WeakComparer(comparer));
}
public WeakKeyDictionary(int capacity, IEqualityComparer comparer)
{
_internalDictionary = new Dictionary(capacity, new WeakComparer(comparer));
}
// FXCop: this is not empty; we need to mark this so we know if a key
// still has an active dictionary at its finalization.
[SuppressMessage("Microsoft.Performance", "CA1821:RemoveEmptyFinalizers")]
~WeakKeyDictionary()
{
_finalized = true;
}
public ICollection Keys
{
get
{
List list = new List();
lock (_[....])
{
foreach (WeakKey key in _internalDictionary.Keys)
{
object k = key.Target;
if (k != null)
{
list.Add((K)k);
}
}
}
return list;
}
}
public ICollection Values
{
get {
lock (_[....]) {
return _internalDictionary.Values;
}
}
}
public int Count
{
get
{
// Ensure a fairly accurate count.
ScavangeLostKeys();
lock (_[....])
{
return _internalDictionary.Count;
}
}
}
public bool IsReadOnly
{
get {
return false;
}
}
[SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", Justification = "LostKeyFinder's purpose is to get garbage collected as soon as posible")]
public V this[K key]
{
get {
lock (_[....]) {
return _internalDictionary[new WeakKey(key)];
}
}
set
{
WeakKey k = new WeakKey(key);
lock (_[....])
{
_internalDictionary[k] = value;
}
// This looks a bit weird but the purpose of the lost key finder is to execute
// code in some future garbage collection phase so we immediately create some garbage.
new LostKeyFinder(this, k);
}
}
public bool TryGetValue(K key, out V value)
{
WeakKey k = new WeakKey(key);
lock (_[....])
{
return _internalDictionary.TryGetValue(k, out value);
}
}
[SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", Justification = "LostKeyFinder's purpose is to get garbage collected as soon as posible")]
public void Add(K key, V value)
{
WeakKey k = new WeakKey(key);
lock (_[....])
{
_internalDictionary.Add(k, value);
}
// This looks a bit weird but the purpose of the lost key finder is to execute
// code in some future garbage collection phase so we immediately create some garbage.
new LostKeyFinder(this, k);
}
public bool ContainsKey(K key)
{
return _internalDictionary.ContainsKey(new WeakKey(key));
}
public bool Remove(K key)
{
lock (_[....])
{
return _internalDictionary.Remove(new WeakKey(key));
}
}
public void Add(KeyValuePair item)
{
Add(item.Key, item.Value);
}
public void Clear()
{
lock (_[....])
{
_internalDictionary.Clear();
}
}
public bool Contains(KeyValuePair item)
{
V value;
bool result;
lock (_[....])
{
result = _internalDictionary.TryGetValue(new WeakKey(item.Key), out value);
}
if (result)
{
return value.Equals(item.Value);
}
else
{
return false;
}
}
public void CopyTo(KeyValuePair[] array, int arrayIndex)
{
lock (_[....])
{
foreach (KeyValuePair item in _internalDictionary)
{
KeyValuePair kv = new KeyValuePair((K)item.Key.Target, item.Value);
array[arrayIndex] = kv;
arrayIndex++;
}
}
}
public bool Remove(KeyValuePair item)
{
WeakKey key = new WeakKey(item.Key);
lock (_[....])
{
return _internalDictionary.Remove(key);
}
}
public IEnumerator> GetEnumerator()
{
List lostKeys = null;
lock (_[....])
{
foreach (KeyValuePair item in _internalDictionary)
{
object k = item.Key.Target;
if (k != null)
{
yield return new KeyValuePair((K)k, item.Value);
}
else
{
if (lostKeys == null)
{
lostKeys = new List();
}
lostKeys.Add(item.Key);
}
}
}
// Recover any lost keys.
if (lostKeys != null)
{
lock (_[....])
{
foreach (WeakKey key in lostKeys)
{
_internalDictionary.Remove(key);
}
}
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
private void ScavangeLostKeys()
{
List lostKeys = null;
lock (_[....])
{
foreach (WeakKey key in _internalDictionary.Keys)
{
if (!key.IsAlive)
{
if (lostKeys == null)
{
lostKeys = new List();
}
lostKeys.Add(key);
}
}
}
if (lostKeys != null)
{
lock (_[....])
{
foreach (WeakKey key in lostKeys)
{
_internalDictionary.Remove(key);
}
}
}
}
private class WeakKey : WeakReference
{
private int _hashCode;
// private GCHandle _gcHandle;
public WeakKey(K key)
: base(key, true)
{
_hashCode = key.GetHashCode();
// Keep the key alive until it is explicitly collected
// _gcHandle = GCHandle.Alloc(this);
}
internal void Release()
{
// _gcHandle.Free();
}
public override int GetHashCode()
{
return _hashCode;
}
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (obj.GetHashCode() != _hashCode)
{
return false;
}
if (obj != this && (!IsAlive || !obj.Equals(Target)))
{
return false;
}
return true;
}
}
private class WeakComparer : IEqualityComparer
{
private IEqualityComparer _comparer;
public WeakComparer()
{
}
public WeakComparer(IEqualityComparer comparer)
{
_comparer = comparer;
}
public bool Equals(WeakKey x, WeakKey y)
{
if (x.GetHashCode() != y.GetHashCode())
{
return false;
}
if (object.ReferenceEquals(x, y))
{
return true;
}
object ref1 = x.Target;
if (ref1 == null)
{
return false;
}
object ref2 = y.Target;
if (ref2 == null)
{
return false;
}
if (_comparer != null)
{
return _comparer.Equals((K)ref1, (K)ref2);
}
else
{
return ref1.Equals(ref2);
}
}
public int GetHashCode(WeakKey obj)
{
return obj.GetHashCode();
}
}
private class LostKeyFinder
{
WeakKeyDictionary _dictionary;
WeakKey _key;
public LostKeyFinder(WeakKeyDictionary dictionary, WeakKey key)
{
_dictionary = dictionary;
_key = key;
}
~LostKeyFinder()
{
if (_dictionary._finalized || _key == null)
{
if (_key != null)
{
_key.Release();
_key = null;
}
return;
}
// if (!_key.IsAlive) {
if (_key.Target == null)
{
lock (_dictionary._[....])
{
_dictionary._internalDictionary.Remove(_key);
}
_key.Release();
_key = null;
}
else if (_dictionary._internalDictionary.ContainsKey(_key))
{
GC.ReRegisterForFinalize(this);
}
}
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//---------------------------------------------------------------
namespace System.Activities.Presentation.Model
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Text;
using System.Runtime.InteropServices;
internal class WeakKeyDictionary : IDictionary
{
private Dictionary _internalDictionary;
private object _[....] = new object();
private bool _finalized;
public WeakKeyDictionary()
{
_internalDictionary = new Dictionary(new WeakComparer());
}
public WeakKeyDictionary(int capacity)
{
_internalDictionary = new Dictionary(capacity, new WeakComparer());
}
public WeakKeyDictionary(IEqualityComparer comparer)
{
_internalDictionary = new Dictionary(new WeakComparer(comparer));
}
public WeakKeyDictionary(int capacity, IEqualityComparer comparer)
{
_internalDictionary = new Dictionary(capacity, new WeakComparer(comparer));
}
// FXCop: this is not empty; we need to mark this so we know if a key
// still has an active dictionary at its finalization.
[SuppressMessage("Microsoft.Performance", "CA1821:RemoveEmptyFinalizers")]
~WeakKeyDictionary()
{
_finalized = true;
}
public ICollection Keys
{
get
{
List list = new List();
lock (_[....])
{
foreach (WeakKey key in _internalDictionary.Keys)
{
object k = key.Target;
if (k != null)
{
list.Add((K)k);
}
}
}
return list;
}
}
public ICollection Values
{
get {
lock (_[....]) {
return _internalDictionary.Values;
}
}
}
public int Count
{
get
{
// Ensure a fairly accurate count.
ScavangeLostKeys();
lock (_[....])
{
return _internalDictionary.Count;
}
}
}
public bool IsReadOnly
{
get {
return false;
}
}
[SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", Justification = "LostKeyFinder's purpose is to get garbage collected as soon as posible")]
public V this[K key]
{
get {
lock (_[....]) {
return _internalDictionary[new WeakKey(key)];
}
}
set
{
WeakKey k = new WeakKey(key);
lock (_[....])
{
_internalDictionary[k] = value;
}
// This looks a bit weird but the purpose of the lost key finder is to execute
// code in some future garbage collection phase so we immediately create some garbage.
new LostKeyFinder(this, k);
}
}
public bool TryGetValue(K key, out V value)
{
WeakKey k = new WeakKey(key);
lock (_[....])
{
return _internalDictionary.TryGetValue(k, out value);
}
}
[SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", Justification = "LostKeyFinder's purpose is to get garbage collected as soon as posible")]
public void Add(K key, V value)
{
WeakKey k = new WeakKey(key);
lock (_[....])
{
_internalDictionary.Add(k, value);
}
// This looks a bit weird but the purpose of the lost key finder is to execute
// code in some future garbage collection phase so we immediately create some garbage.
new LostKeyFinder(this, k);
}
public bool ContainsKey(K key)
{
return _internalDictionary.ContainsKey(new WeakKey(key));
}
public bool Remove(K key)
{
lock (_[....])
{
return _internalDictionary.Remove(new WeakKey(key));
}
}
public void Add(KeyValuePair item)
{
Add(item.Key, item.Value);
}
public void Clear()
{
lock (_[....])
{
_internalDictionary.Clear();
}
}
public bool Contains(KeyValuePair item)
{
V value;
bool result;
lock (_[....])
{
result = _internalDictionary.TryGetValue(new WeakKey(item.Key), out value);
}
if (result)
{
return value.Equals(item.Value);
}
else
{
return false;
}
}
public void CopyTo(KeyValuePair[] array, int arrayIndex)
{
lock (_[....])
{
foreach (KeyValuePair item in _internalDictionary)
{
KeyValuePair kv = new KeyValuePair((K)item.Key.Target, item.Value);
array[arrayIndex] = kv;
arrayIndex++;
}
}
}
public bool Remove(KeyValuePair item)
{
WeakKey key = new WeakKey(item.Key);
lock (_[....])
{
return _internalDictionary.Remove(key);
}
}
public IEnumerator> GetEnumerator()
{
List lostKeys = null;
lock (_[....])
{
foreach (KeyValuePair item in _internalDictionary)
{
object k = item.Key.Target;
if (k != null)
{
yield return new KeyValuePair((K)k, item.Value);
}
else
{
if (lostKeys == null)
{
lostKeys = new List();
}
lostKeys.Add(item.Key);
}
}
}
// Recover any lost keys.
if (lostKeys != null)
{
lock (_[....])
{
foreach (WeakKey key in lostKeys)
{
_internalDictionary.Remove(key);
}
}
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
private void ScavangeLostKeys()
{
List lostKeys = null;
lock (_[....])
{
foreach (WeakKey key in _internalDictionary.Keys)
{
if (!key.IsAlive)
{
if (lostKeys == null)
{
lostKeys = new List();
}
lostKeys.Add(key);
}
}
}
if (lostKeys != null)
{
lock (_[....])
{
foreach (WeakKey key in lostKeys)
{
_internalDictionary.Remove(key);
}
}
}
}
private class WeakKey : WeakReference
{
private int _hashCode;
// private GCHandle _gcHandle;
public WeakKey(K key)
: base(key, true)
{
_hashCode = key.GetHashCode();
// Keep the key alive until it is explicitly collected
// _gcHandle = GCHandle.Alloc(this);
}
internal void Release()
{
// _gcHandle.Free();
}
public override int GetHashCode()
{
return _hashCode;
}
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (obj.GetHashCode() != _hashCode)
{
return false;
}
if (obj != this && (!IsAlive || !obj.Equals(Target)))
{
return false;
}
return true;
}
}
private class WeakComparer : IEqualityComparer
{
private IEqualityComparer _comparer;
public WeakComparer()
{
}
public WeakComparer(IEqualityComparer comparer)
{
_comparer = comparer;
}
public bool Equals(WeakKey x, WeakKey y)
{
if (x.GetHashCode() != y.GetHashCode())
{
return false;
}
if (object.ReferenceEquals(x, y))
{
return true;
}
object ref1 = x.Target;
if (ref1 == null)
{
return false;
}
object ref2 = y.Target;
if (ref2 == null)
{
return false;
}
if (_comparer != null)
{
return _comparer.Equals((K)ref1, (K)ref2);
}
else
{
return ref1.Equals(ref2);
}
}
public int GetHashCode(WeakKey obj)
{
return obj.GetHashCode();
}
}
private class LostKeyFinder
{
WeakKeyDictionary _dictionary;
WeakKey _key;
public LostKeyFinder(WeakKeyDictionary dictionary, WeakKey key)
{
_dictionary = dictionary;
_key = key;
}
~LostKeyFinder()
{
if (_dictionary._finalized || _key == null)
{
if (_key != null)
{
_key.Release();
_key = null;
}
return;
}
// if (!_key.IsAlive) {
if (_key.Target == null)
{
lock (_dictionary._[....])
{
_dictionary._internalDictionary.Remove(_key);
}
_key.Release();
_key = null;
}
else if (_dictionary._internalDictionary.ContainsKey(_key))
{
GC.ReRegisterForFinalize(this);
}
}
}
}
}
// 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
- DataServiceExpressionVisitor.cs
- DocumentApplicationJournalEntry.cs
- CheckStoreFileValidityRequest.cs
- Cursor.cs
- TimeoutValidationAttribute.cs
- ScriptMethodAttribute.cs
- UIServiceHelper.cs
- ServiceEndpointElement.cs
- ErrorStyle.cs
- TextTreeDeleteContentUndoUnit.cs
- LinkButton.cs
- IResourceProvider.cs
- ButtonBaseAdapter.cs
- PropertyChange.cs
- Visitor.cs
- ObjectItemCollection.cs
- CodeAttributeArgumentCollection.cs
- InheritanceContextChangedEventManager.cs
- ComponentCollection.cs
- ByteConverter.cs
- SQLUtility.cs
- DynamicResourceExtension.cs
- MeasurementDCInfo.cs
- HttpException.cs
- XmlSchemaSimpleTypeRestriction.cs
- TransferRequestHandler.cs
- TraceContext.cs
- exports.cs
- Delay.cs
- EntityDataReader.cs
- MULTI_QI.cs
- BufferedReceiveElement.cs
- SqlAliasesReferenced.cs
- MarkupWriter.cs
- RangeValuePattern.cs
- SerialPort.cs
- DrawListViewItemEventArgs.cs
- ShapingEngine.cs
- ServiceProviders.cs
- XPathChildIterator.cs
- SqlServer2KCompatibilityCheck.cs
- WebResourceUtil.cs
- MetricEntry.cs
- ScriptingScriptResourceHandlerSection.cs
- StringConverter.cs
- SoapExtension.cs
- InputDevice.cs
- FastEncoderStatics.cs
- BufferedStream.cs
- ErrorStyle.cs
- ConfigXmlDocument.cs
- SlotInfo.cs
- IndentedWriter.cs
- DataGridTablesFactory.cs
- CompatibleComparer.cs
- MethodRental.cs
- BinaryWriter.cs
- ManifestSignatureInformation.cs
- X509ChainPolicy.cs
- SessionPageStateSection.cs
- ManipulationInertiaStartingEventArgs.cs
- DbConnectionOptions.cs
- CodeDOMUtility.cs
- SecurityManager.cs
- IsolatedStorage.cs
- EventWaitHandleSecurity.cs
- AccessViolationException.cs
- PolicyUnit.cs
- VideoDrawing.cs
- DataGridViewCellMouseEventArgs.cs
- CodeVariableDeclarationStatement.cs
- Literal.cs
- SignatureGenerator.cs
- BoolLiteral.cs
- Section.cs
- ObjectContext.cs
- ErrorWrapper.cs
- ColumnWidthChangedEvent.cs
- CreateParams.cs
- ItemsControlAutomationPeer.cs
- ValueType.cs
- MessageDispatch.cs
- BooleanSwitch.cs
- CmsUtils.cs
- LabelEditEvent.cs
- Light.cs
- Fault.cs
- XmlILAnnotation.cs
- WebPartUserCapability.cs
- CommandField.cs
- SmiXetterAccessMap.cs
- OverlappedAsyncResult.cs
- EllipseGeometry.cs
- CachedFontFace.cs
- SystemWebCachingSectionGroup.cs
- Route.cs
- ControlValuePropertyAttribute.cs
- BasicExpandProvider.cs
- MultiView.cs
- TextServicesCompartmentContext.cs