WeakReferenceList.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Shared / MS / Internal / WeakReferenceList.cs / 1305600 / 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();
        }

        public bool Contains(object item) 
        {
            Debug.Assert(null != item, "WeakReferenceList.Contains() should not be passed null."); 
            lock (base.SyncRoot) 
            {
                int index = FindWeakReference(item); 

                // If the object is already on the list then
                // return true
                if (index >= 0) 
                    return true;
 
                return false; 
            }
        } 

        public int Count
        {
            get 
            {
                int count = 0; 
                lock (base.SyncRoot) 
                {
                    count = base.LiveList.Count; 
                }
                return count;
            }
 

        } 
 
        /// 
        ///   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."); 
            return Add(obj, false /*skipFind*/); 

        } 

        //Will insert a new WeakREference into the list.
        //The object bein inserted MUST be unique as there is no check for it.
        public bool Add(object obj, bool skipFind) 
        {
            Debug.Assert(null!=obj, "WeakReferenceList.Add() should not be passed null."); 
            lock(base.SyncRoot) 
            {
                if (!skipFind && FindWeakReference(obj) >= 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

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK