Beispiel #1
0
        private void AddListener(object source, PropertyDescriptor pd, IWeakEventListener listener, EventHandler <ValueChangedEventArgs> handler)
        {
            using (WriteLock)
            {
                HybridDictionary dict = (HybridDictionary)this[source];

                if (dict == null)
                {
                    // no entry in the hashtable - add a new one
                    dict = new HybridDictionary();

                    this[source] = dict;
                }

                ValueChangedRecord record = (ValueChangedRecord)dict[pd];

                if (record == null)
                {
                    // no entry in the dictionary - add a new one
                    record = new ValueChangedRecord(this, source, pd);

                    dict[pd] = record;
                }

                // add a listener to the list
                record.Add(listener, handler);

                // schedule a cleanup pass
                ScheduleCleanup();
            }
        }
Beispiel #2
0
        private void RemoveListener(object source, PropertyDescriptor pd, IWeakEventListener listener, EventHandler <ValueChangedEventArgs> handler)
        {
            using (WriteLock)
            {
                HybridDictionary dict = (HybridDictionary)this[source];

                if (dict != null)
                {
                    ValueChangedRecord record = (ValueChangedRecord)dict[pd];

                    if (record != null)
                    {
                        // remove a listener from the list
                        record.Remove(listener, handler);

                        // when the last listener goes away, remove the list
                        if (record.IsEmpty)
                        {
                            dict.Remove(pd);
                        }
                    }

                    if (dict.Count == 0)
                    {
                        Remove(source);
                    }
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// Remove a listener to the named property (empty means "any property")</summary>
        /// <param name="source">Source of the event</param>
        /// <param name="listener">The listener to remove</param>
        /// <param name="pd">Property descriptor for the value</param>
        private void PrivateRemoveListener(object source, IWeakEventListener listener, PropertyDescriptor pd)
        {
            Debug.Assert(listener != null && source != null && pd != null,
                         "Listener, source, and pd of event cannot be null");

            using (WriteLock)
            {
                HybridDictionary dict = (HybridDictionary)this[source];

                if (dict != null)
                {
                    ValueChangedRecord record = (ValueChangedRecord)dict[pd];

                    if (record != null)
                    {
                        // remove a listener from the list
                        record.Remove(listener);

                        // when the last listener goes away, remove the list
                        if (record.IsEmpty)
                        {
                            dict.Remove(pd);
                        }
                    }

                    if (dict.Count == 0)
                    {
                        Remove(source);
                    }
                }
            }
        }
Beispiel #4
0
        /// <summary>
        /// Add a listener to the given property</summary>
        /// <param name="source">Source of the event</param>
        /// <param name="listener">The listener to add</param>
        /// <param name="pd">Property descriptor for the value</param>
        private void PrivateAddListener(object source, IWeakEventListener listener, PropertyDescriptor pd)
        {
            Debug.Assert(listener != null && source != null && pd != null,
                         "Listener, source, and pd of event cannot be null");

            using (WriteLock)
            {
                HybridDictionary dict = (HybridDictionary)this[source];

                if (dict == null)
                {
                    // no entry in the hashtable - add a new one
                    dict = new HybridDictionary();

                    this[source] = dict;
                }

                ValueChangedRecord record = (ValueChangedRecord)dict[pd];

                if (record == null)
                {
                    // no entry in the dictionary - add a new one
                    record = new ValueChangedRecord(this, source, pd);

                    dict[pd] = record;
                }

                // add a listener to the list
                record.Add(listener);

                // schedule a cleanup pass
                ScheduleCleanup();
            }
        }
Beispiel #5
0
        /// <summary>
        /// Remove dead entries from the data for the given source.   Returns true if
        /// some entries were actually removed.
        /// </summary>
        protected override bool Purge(object source, object data, bool purgeAll)
        {
            bool foundDirt = false;

            HybridDictionary dict = (HybridDictionary)data;

            // copy the keys into a separate array, so that later on
            // we can change the dictionary while iterating over the keys
            ICollection ic = dict.Keys;

            PropertyDescriptor[] keys = new PropertyDescriptor[ic.Count];
            ic.CopyTo(keys, 0);

            for (int i = keys.Length - 1; i >= 0; --i)
            {
                // for each key, remove dead entries in its list
                bool removeList = purgeAll || source == null;

                ValueChangedRecord record = (ValueChangedRecord)dict[keys[i]];

                if (!removeList)
                {
                    if (record.Purge())
                    {
                        foundDirt = true;
                    }

                    removeList = record.IsEmpty;
                }

                // if there are no more entries, remove the key
                if (removeList)
                {
                    record.StopListening();
                    if (!purgeAll)
                    {
                        dict.Remove(keys[i]);
                    }
                }
            }

            // if there are no more listeners at all, remove the entry from
            // the main table
            if (dict.Count == 0)
            {
                foundDirt = true;
                if (source != null)     // source may have been GC'd
                {
                    this.Remove(source);
                }
            }

            return(foundDirt);
        }
Beispiel #6
0
        /// <summary>
        /// Add a listener to the given property</summary>
        /// <param name="source">Source of the event</param>
        /// <param name="listener">The listener to add</param>
        /// <param name="pd">Property descriptor for the value</param>
        private void PrivateAddListener(object source, IWeakEventListener listener, PropertyDescriptor pd)
        {
            Debug.Assert(listener != null && source != null && pd != null,
                "Listener, source, and pd of event cannot be null");

            using (WriteLock)
            {
                HybridDictionary dict = (HybridDictionary)this[source];

                if (dict == null)
                {
                    // no entry in the hashtable - add a new one
                    dict = new HybridDictionary();

                    this[source] = dict;
                }

                ValueChangedRecord record = (ValueChangedRecord)dict[pd];

                if (record == null)
                {
                    // no entry in the dictionary - add a new one
                    record = new ValueChangedRecord(this, source, pd);

                    dict[pd] = record;
                }

                // add a listener to the list
                record.Add(listener);

                // schedule a cleanup pass
                ScheduleCleanup();
            }
        }
Beispiel #7
0
        /// <summary>
        /// Remove dead entries from the data for the given source.   Returns true if
        /// some entries were actually removed.
        /// </summary>
        protected override bool Purge(object source, object data, bool purgeAll)
        {
            bool foundDirt = false;

            HybridDictionary dict = (HybridDictionary)data;

            if (!MS.Internal.BaseAppContextSwitches.EnableWeakEventMemoryImprovements)
            {
                // copy the keys into a separate array, so that later on
                // we can change the dictionary while iterating over the keys
                ICollection          ic   = dict.Keys;
                PropertyDescriptor[] keys = new PropertyDescriptor[ic.Count];
                ic.CopyTo(keys, 0);

                for (int i = keys.Length - 1; i >= 0; --i)
                {
                    // for each key, remove dead entries in its list
                    bool removeList = purgeAll || source == null;

                    ValueChangedRecord record = (ValueChangedRecord)dict[keys[i]];

                    if (!removeList)
                    {
                        if (record.Purge())
                        {
                            foundDirt = true;
                        }

                        removeList = record.IsEmpty;
                    }

                    // if there are no more entries, remove the key
                    if (removeList)
                    {
                        record.StopListening();
                        if (!purgeAll)
                        {
                            dict.Remove(keys[i]);
                        }
                    }
                }

#if WeakEventTelemetry
                LogAllocation(ic.GetType(), 1, 12);                     // dict.Keys - Hashtable+KeyCollection
                LogAllocation(typeof(String[]), 1, 12 + ic.Count * 4);  // keys
#endif
            }
            else
            {
                Debug.Assert(_toRemove.Count == 0, "to-remove list should be empty");

                // enumerate the dictionary using IDE explicitly rather than
                // foreach, to avoid allocating temporary DictionaryEntry objects
                IDictionaryEnumerator ide = dict.GetEnumerator() as IDictionaryEnumerator;
                while (ide.MoveNext())
                {
                    // for each key, remove dead entries in its list
                    bool removeList = purgeAll || source == null;

                    ValueChangedRecord record = (ValueChangedRecord)ide.Value;

                    if (!removeList)
                    {
                        if (record.Purge())
                        {
                            foundDirt = true;
                        }

                        removeList = record.IsEmpty;
                    }

                    // if there are no more entries, remove the key
                    if (removeList)
                    {
                        record.StopListening();
                        if (!purgeAll)
                        {
                            _toRemove.Add((PropertyDescriptor)ide.Key);
                        }
                    }
                }

                // do the actual removal (outside the dictionary iteration)
                if (_toRemove.Count > 0)
                {
                    foreach (PropertyDescriptor key in _toRemove)
                    {
                        dict.Remove(key);
                    }
                    _toRemove.Clear();
                    _toRemove.TrimExcess();
                }

#if WeakEventTelemetry
                Type enumeratorType = ide.GetType();
                if (enumeratorType.Name.IndexOf("NodeEnumerator") >= 0)
                {
                    LogAllocation(enumeratorType, 1, 24);                    // ListDictionary+NodeEnumerator
                }
                else
                {
                    LogAllocation(enumeratorType, 1, 36);                    // Hashtable+HashtableEnumerator
                }
#endif
            }


            // if there are no more listeners at all, remove the entry from
            // the main table
            if (dict.Count == 0)
            {
                foundDirt = true;
                if (source != null)     // source may have been GC'd
                {
                    this.Remove(source);
                }
            }

            return(foundDirt);
        }
        private void AddListener(object source, PropertyDescriptor pd, IWeakEventListener listener, EventHandler<ValueChangedEventArgs> handler)
        {
            using (WriteLock)
            {
                HybridDictionary dict = (HybridDictionary)this[source];

                if (dict == null)
                {
                    // no entry in the hashtable - add a new one
                    dict = new HybridDictionary();

                    this[source] = dict;
                }

                ValueChangedRecord record = (ValueChangedRecord)dict[pd];

                if (record == null)
                {
                    // no entry in the dictionary - add a new one
                    record = new ValueChangedRecord(this, source, pd);

                    dict[pd] = record;
                }

                // add a listener to the list
                record.Add(listener, handler);

                // schedule a cleanup pass
                ScheduleCleanup();
            }
        }