Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Shared / MS / Internal / WeakReferenceList.cs / 1 / WeakReferenceList.cs
using System; using System.Collections; using System.Diagnostics; #if WINDOWS_BASE using MS.Internal.WindowsBase; #elif PRESENTATION_CORE using MS.Internal.PresentationCore; #elif PRESENTATIONFRAMEWORK using MS.Internal.PresentationFramework; #elif DRT using MS.Internal.Drt; #else #error Attempt to use FriendAccessAllowedAttribute from an unknown assembly. using MS.Internal.YourAssemblyName; #endif namespace MS.Internal { ////// This is a Cached ThreadSafe ArrayList of WeakReferences. /// - When the "List" property is requested a readonly reference to the /// list is returned and a reference to the readonly list is cached. /// - If the "List" is requested again, the same cached reference is returned. /// - When the list is modified, if a readonly reference is present in the /// cache then the list is copied before it is modified and the readonly list is /// released from the cache. /// [FriendAccessAllowed] internal class WeakReferenceList : CopyOnWriteList, IEnumerable { public WeakReferenceList():base(null) { } public WeakReferenceList(object syncRoot):base(syncRoot) { } public WeakReferenceListEnumerator GetEnumerator() { return new WeakReferenceListEnumerator(List); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } ////// Add a weak reference to the List. /// Returns true if successfully added. /// Returns false if object is already on the list. /// public override bool Add(object obj) { Debug.Assert(null!=obj, "WeakReferenceList.Add() should not be passed null."); lock(base.SyncRoot) { int index = FindWeakReference(obj); // If the object is already on the list then // we are done. (return false) if(index >= 0) return false; return base.Internal_Add(new WeakReference(obj)); } } ////// Remove a weak reference to the List. /// Returns true if successfully added. /// Returns false if object is already on the list. /// public override bool Remove(object obj) { Debug.Assert(null!=obj, "WeakReferenceList.Remove() should not be passed null."); lock(base.SyncRoot) { int index = FindWeakReference(obj); // If the object is not on the list then // we are done. (return false) if(index < 0) return false; return base.RemoveAt(index); } } ////// Insert a weak reference into the List. /// Returns true if successfully inserted. /// Returns false if object is already on the list. /// public bool Insert(int index, object obj) { Debug.Assert(null!=obj, "WeakReferenceList.Add() should not be passed null."); lock(base.SyncRoot) { int existingIndex = FindWeakReference(obj); // If the object is already on the list then // we are done. (return false) if(existingIndex >= 0) return false; return base.Internal_Insert(index, new WeakReference(obj)); } } ////// Find an object on the List. /// Also cleans up dead weakreferences. /// private int FindWeakReference(object obj) { // syncRoot Lock MUST be held by the caller. // Search the LiveList looking for the object, also remove any // dead references.we find. These two operations are combinded // to prevent having to walk the list twice. // // We use the "LiveList" to avoid snapping a Clone everytime we // Change something. // To do this correctly you need to understand how the base class // virtualizes the Copy On Write. ArrayList list = base.LiveList; int foundItem = -1; for(int i = 0; i < list.Count; i++) { WeakReference weakRef = (WeakReference) list[i]; if(weakRef.IsAlive) { if(obj == weakRef.Target) foundItem = i; } else { // Removing dead refs should not invalidate "foundItem" above. // Call the base RemoveAt to preserve the Copy on Write // virtualization. ie. list.RemoveAt(i) would be WRONG! // The RemoveAt call might Clone the LiveList (the first // time only) so we should get a new reference to it. base.RemoveAt(i); list = base.LiveList; // Also the ArrayList will copy-up to fill the Removed element // so back up and do the same index again. i -= 1; } } return foundItem; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. using System; using System.Collections; using System.Diagnostics; #if WINDOWS_BASE using MS.Internal.WindowsBase; #elif PRESENTATION_CORE using MS.Internal.PresentationCore; #elif PRESENTATIONFRAMEWORK using MS.Internal.PresentationFramework; #elif DRT using MS.Internal.Drt; #else #error Attempt to use FriendAccessAllowedAttribute from an unknown assembly. using MS.Internal.YourAssemblyName; #endif namespace MS.Internal { ////// This is a Cached ThreadSafe ArrayList of WeakReferences. /// - When the "List" property is requested a readonly reference to the /// list is returned and a reference to the readonly list is cached. /// - If the "List" is requested again, the same cached reference is returned. /// - When the list is modified, if a readonly reference is present in the /// cache then the list is copied before it is modified and the readonly list is /// released from the cache. /// [FriendAccessAllowed] internal class WeakReferenceList : CopyOnWriteList, IEnumerable { public WeakReferenceList():base(null) { } public WeakReferenceList(object syncRoot):base(syncRoot) { } public WeakReferenceListEnumerator GetEnumerator() { return new WeakReferenceListEnumerator(List); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } ////// Add a weak reference to the List. /// Returns true if successfully added. /// Returns false if object is already on the list. /// public override bool Add(object obj) { Debug.Assert(null!=obj, "WeakReferenceList.Add() should not be passed null."); lock(base.SyncRoot) { int index = FindWeakReference(obj); // If the object is already on the list then // we are done. (return false) if(index >= 0) return false; return base.Internal_Add(new WeakReference(obj)); } } ////// Remove a weak reference to the List. /// Returns true if successfully added. /// Returns false if object is already on the list. /// public override bool Remove(object obj) { Debug.Assert(null!=obj, "WeakReferenceList.Remove() should not be passed null."); lock(base.SyncRoot) { int index = FindWeakReference(obj); // If the object is not on the list then // we are done. (return false) if(index < 0) return false; return base.RemoveAt(index); } } ////// Insert a weak reference into the List. /// Returns true if successfully inserted. /// Returns false if object is already on the list. /// public bool Insert(int index, object obj) { Debug.Assert(null!=obj, "WeakReferenceList.Add() should not be passed null."); lock(base.SyncRoot) { int existingIndex = FindWeakReference(obj); // If the object is already on the list then // we are done. (return false) if(existingIndex >= 0) return false; return base.Internal_Insert(index, new WeakReference(obj)); } } ////// Find an object on the List. /// Also cleans up dead weakreferences. /// private int FindWeakReference(object obj) { // syncRoot Lock MUST be held by the caller. // Search the LiveList looking for the object, also remove any // dead references.we find. These two operations are combinded // to prevent having to walk the list twice. // // We use the "LiveList" to avoid snapping a Clone everytime we // Change something. // To do this correctly you need to understand how the base class // virtualizes the Copy On Write. ArrayList list = base.LiveList; int foundItem = -1; for(int i = 0; i < list.Count; i++) { WeakReference weakRef = (WeakReference) list[i]; if(weakRef.IsAlive) { if(obj == weakRef.Target) foundItem = i; } else { // Removing dead refs should not invalidate "foundItem" above. // Call the base RemoveAt to preserve the Copy on Write // virtualization. ie. list.RemoveAt(i) would be WRONG! // The RemoveAt call might Clone the LiveList (the first // time only) so we should get a new reference to it. base.RemoveAt(i); list = base.LiveList; // Also the ArrayList will copy-up to fill the Removed element // so back up and do the same index again. i -= 1; } } return foundItem; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- RegexReplacement.cs
- ObjectSelectorEditor.cs
- IncrementalReadDecoders.cs
- ReferenceSchema.cs
- UserInitiatedNavigationPermission.cs
- Effect.cs
- IPAddressCollection.cs
- WebPartEditorOkVerb.cs
- ObjectDataSource.cs
- SurrogateSelector.cs
- XmlAnyElementAttribute.cs
- TransformedBitmap.cs
- DiscreteKeyFrames.cs
- UnmanagedMemoryStreamWrapper.cs
- SafeNativeMethodsCLR.cs
- ResetableIterator.cs
- XmlSignatureManifest.cs
- Focus.cs
- DataGridSortingEventArgs.cs
- ScrollableControl.cs
- CodeGroup.cs
- Pair.cs
- NamespaceList.cs
- Assembly.cs
- DocumentGridContextMenu.cs
- WebPartDisplayModeCollection.cs
- SimpleWorkerRequest.cs
- XsltArgumentList.cs
- AsyncPostBackErrorEventArgs.cs
- SourceChangedEventArgs.cs
- ConfigurationSettings.cs
- PeerEndPoint.cs
- Padding.cs
- SrgsToken.cs
- DesignerTextBoxAdapter.cs
- TypeElement.cs
- AnnotationAuthorChangedEventArgs.cs
- CharEntityEncoderFallback.cs
- HtmlFormParameterReader.cs
- PersonalizableTypeEntry.cs
- InputQueueChannelAcceptor.cs
- WinFormsSecurity.cs
- CodeDirectiveCollection.cs
- ManagedWndProcTracker.cs
- ButtonBase.cs
- XmlSchemaComplexContent.cs
- OracleMonthSpan.cs
- DesignerActionService.cs
- UserPrincipalNameElement.cs
- HyperLinkStyle.cs
- JumpPath.cs
- XpsS0ValidatingLoader.cs
- TextSpanModifier.cs
- NotFiniteNumberException.cs
- LineGeometry.cs
- SqlDependencyListener.cs
- WinInet.cs
- DBSqlParserColumn.cs
- ActionMessageFilterTable.cs
- BroadcastEventHelper.cs
- WorkflowClientDeliverMessageWrapper.cs
- DesignerActionListCollection.cs
- HttpConfigurationContext.cs
- ToolStripRendererSwitcher.cs
- VisualStyleInformation.cs
- filewebresponse.cs
- EventDriven.cs
- TreeViewBindingsEditorForm.cs
- PropertyTabAttribute.cs
- RbTree.cs
- PtsContext.cs
- QilUnary.cs
- InlineCollection.cs
- WSDualHttpSecurityMode.cs
- OracleTimeSpan.cs
- ProtectedConfiguration.cs
- XmlSchemaImport.cs
- TextComposition.cs
- SizeConverter.cs
- Cursor.cs
- PerspectiveCamera.cs
- RtfControls.cs
- _Rfc2616CacheValidators.cs
- LocalizationParserHooks.cs
- Compiler.cs
- CurrentChangedEventManager.cs
- LinkUtilities.cs
- PackageRelationship.cs
- UndirectedGraph.cs
- ViewCellSlot.cs
- WebResponse.cs
- ExpressionNode.cs
- SimpleMailWebEventProvider.cs
- handlecollector.cs
- XPathNavigatorKeyComparer.cs
- QueueException.cs
- ParseChildrenAsPropertiesAttribute.cs
- MenuItem.cs
- SessionEndedEventArgs.cs
- VolatileEnlistmentMultiplexing.cs