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
- WeakReadOnlyCollection.cs
- AccessDataSourceView.cs
- EntityContainerAssociationSetEnd.cs
- GeometryGroup.cs
- TimeEnumHelper.cs
- SmiMetaData.cs
- PropertyValueChangedEvent.cs
- Stroke2.cs
- DesignerValidatorAdapter.cs
- XmlNode.cs
- SimpleNameService.cs
- httpserverutility.cs
- AppearanceEditorPart.cs
- StyleCollection.cs
- IntAverageAggregationOperator.cs
- HtmlSelect.cs
- SwitchAttribute.cs
- AtomServiceDocumentSerializer.cs
- StylusLogic.cs
- XomlCompilerResults.cs
- Visual.cs
- CategoryAttribute.cs
- ColumnResizeUndoUnit.cs
- TabletDevice.cs
- HtmlSelect.cs
- DocobjHost.cs
- PropertyPathConverter.cs
- ASCIIEncoding.cs
- BuilderInfo.cs
- UnsafeCollabNativeMethods.cs
- SqlConnectionFactory.cs
- TreeViewDataItemAutomationPeer.cs
- MonitoringDescriptionAttribute.cs
- CombinedHttpChannel.cs
- Property.cs
- SmiRecordBuffer.cs
- CodeNamespaceCollection.cs
- ToolboxDataAttribute.cs
- ObjectPropertyMapping.cs
- ProcessModelInfo.cs
- StrokeFIndices.cs
- XamlSerializationHelper.cs
- EntityDataSourceWrapperCollection.cs
- PropertySet.cs
- SourceElementsCollection.cs
- ExtenderControl.cs
- Convert.cs
- RouteItem.cs
- DropSource.cs
- Decimal.cs
- ThrowHelper.cs
- BrowserCapabilitiesCodeGenerator.cs
- SimpleBitVector32.cs
- HMACSHA256.cs
- ToolStripRenderEventArgs.cs
- RegistrationServices.cs
- TreeNodeCollectionEditor.cs
- MatchingStyle.cs
- CellParagraph.cs
- MenuItem.cs
- ComponentChangingEvent.cs
- SizeAnimationClockResource.cs
- HMACSHA1.cs
- XmlWrappingReader.cs
- NonValidatingSecurityTokenAuthenticator.cs
- HostedHttpContext.cs
- BlurEffect.cs
- XamlToRtfParser.cs
- dbenumerator.cs
- XmlSchemaProviderAttribute.cs
- TemplateBindingExpression.cs
- OdbcConnectionFactory.cs
- DebugView.cs
- UserNamePasswordValidator.cs
- FileLevelControlBuilderAttribute.cs
- DelegatingStream.cs
- BindingCollection.cs
- CompositionCommandSet.cs
- UndirectedGraph.cs
- Operator.cs
- ObjectContext.cs
- StringAnimationUsingKeyFrames.cs
- IsolatedStorageFileStream.cs
- StylusPointCollection.cs
- DataBoundLiteralControl.cs
- SQLDateTimeStorage.cs
- MeshGeometry3D.cs
- GeometryHitTestParameters.cs
- EntityProviderServices.cs
- AssemblyName.cs
- CreateUserErrorEventArgs.cs
- AuthenticationModuleElementCollection.cs
- EventHandlerList.cs
- RegexNode.cs
- CryptoHelper.cs
- DataControlFieldCollection.cs
- SqlCommandBuilder.cs
- MonitoringDescriptionAttribute.cs
- EpmSyndicationContentSerializer.cs
- WsatTransactionFormatter.cs