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
- Compiler.cs
- CodeDirectionExpression.cs
- TextEditorCharacters.cs
- ClientCredentials.cs
- DataControlCommands.cs
- RegexBoyerMoore.cs
- ClientUtils.cs
- RuntimeResourceSet.cs
- MulticastDelegate.cs
- SoapTypeAttribute.cs
- WebAdminConfigurationHelper.cs
- OleDbEnumerator.cs
- WebServiceMethodData.cs
- TransactedBatchingBehavior.cs
- XslCompiledTransform.cs
- IndexedGlyphRun.cs
- StateFinalizationDesigner.cs
- Pts.cs
- ObjectListTitleAttribute.cs
- ButtonBaseAdapter.cs
- ListenUriMode.cs
- VariantWrapper.cs
- SmtpSection.cs
- ClusterSafeNativeMethods.cs
- CodeDomConfigurationHandler.cs
- CompositeActivityDesigner.cs
- ScriptHandlerFactory.cs
- CrossSiteScriptingValidation.cs
- User.cs
- DiagnosticsConfiguration.cs
- GlobalId.cs
- TimeSpanValidatorAttribute.cs
- TokenCreationException.cs
- ScriptingScriptResourceHandlerSection.cs
- MonthChangedEventArgs.cs
- DataPager.cs
- Row.cs
- SqlDataReader.cs
- Filter.cs
- ThicknessAnimation.cs
- Drawing.cs
- Method.cs
- CloudCollection.cs
- securitycriticaldataClass.cs
- ResumeStoryboard.cs
- BinaryMethodMessage.cs
- HttpContext.cs
- Binding.cs
- ControlUtil.cs
- TypeCodeDomSerializer.cs
- CapabilitiesUse.cs
- DependencyPropertyChangedEventArgs.cs
- DetailsViewCommandEventArgs.cs
- BamlTreeNode.cs
- WinFormsSecurity.cs
- FixedPage.cs
- XmlSchemaAnnotation.cs
- LinqDataSourceInsertEventArgs.cs
- DesignerTransactionCloseEvent.cs
- ComponentConverter.cs
- AttributeCollection.cs
- PropertyTabChangedEvent.cs
- PtsCache.cs
- XmlConvert.cs
- RelatedImageListAttribute.cs
- CustomAttributeFormatException.cs
- CodeMemberField.cs
- StyleXamlParser.cs
- QueueTransferProtocol.cs
- Timeline.cs
- CallContext.cs
- PageParserFilter.cs
- BrowserCapabilitiesCodeGenerator.cs
- StorageComplexTypeMapping.cs
- Scripts.cs
- OdbcParameterCollection.cs
- ListViewGroupItemCollection.cs
- EDesignUtil.cs
- TransactionCache.cs
- GridViewItemAutomationPeer.cs
- HandlerBase.cs
- List.cs
- DataGridViewImageColumn.cs
- EventProviderBase.cs
- TextAnchor.cs
- HttpWebResponse.cs
- OracleRowUpdatedEventArgs.cs
- SelectionProviderWrapper.cs
- DataComponentGenerator.cs
- StructuredType.cs
- CodeAttributeDeclaration.cs
- SafeFileMappingHandle.cs
- ConfigXmlCDataSection.cs
- PersonalizationDictionary.cs
- TcpAppDomainProtocolHandler.cs
- ArraySortHelper.cs
- PermissionListSet.cs
- ConfigurationLocation.cs
- FunctionImportMapping.cs
- AssociationType.cs