예제 #1
0
            /// <summary>
            ///   Returns an enumerator that iterates through the collection.
            /// </summary>
            /// <returns>
            ///   A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.
            /// </returns>
            /// <filterpriority>1</filterpriority>
            public IEnumerator <TValue> GetEnumerator()
            {
                List <Guid> deadGuids = new List <Guid>();

                foreach (KeyValuePair <Guid, WeakReference <TValue> > kvp in _dictionary)
                {
                    Debug.Assert(kvp.Value != null);

                    TValue target;
                    if (!kvp.Value.TryGetTarget(out target))
                    {
                        deadGuids.Add(kvp.Key);
                    }
                    else
                    {
                        yield return(target);
                    }
                }
                foreach (Guid guid in deadGuids)
                {
                    WeakReference <TValue> weakReference;
                    if (!_dictionary.TryRemove(guid, out weakReference) ||
                        !_parent._observable)
                    {
                        continue;
                    }

                    ObservableWeakReference <TValue> owf = weakReference as ObservableWeakReference <TValue>;
                    if (owf != null)
                    {
                        owf.Dispose();
                    }
                }
            }
        /// <summary>
        ///   Register the finalize event where appropriate.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="weakReference">The weak reference.</param>
        private void RegisterFinalize([NotNull] TKey key, [CanBeNull] WeakReference <TValue> weakReference)
        {
            if (!_observable ||
                (weakReference == null))
            {
                return;
            }
            ObservableWeakReference <TValue> owf = weakReference as ObservableWeakReference <TValue>;

            if (owf == null)
            {
                return;
            }
            owf.Finalized += (s, e) =>
            {
                WeakReference <TValue> oldwr;

                if (_dictionary.TryRemove(key, out oldwr) &&
                    (oldwr != weakReference))
                {
                    // If we removed something else, add it back!
                    _dictionary.TryAdd(key, oldwr);
                }
                owf.Dispose();
            };
        }
예제 #3
0
            /// <summary>
            ///   Removes the specified value from the group.
            /// </summary>
            /// <param name="value">The value to remove.</param>
            /// <returns>
            ///   Returns <see langword="true"/> if the value was successfully removed; otherwise returns <see langword="false"/>.
            /// </returns>
            public bool Remove(TValue value)
            {
                // Scan dictionary looking for dead elements
                List <Guid> deadGuids = new List <Guid>();
                bool        found     = false;

                foreach (KeyValuePair <Guid, WeakReference <TValue> > kvp in _dictionary)
                {
                    Debug.Assert(kvp.Value != null);

                    TValue v;
                    if (!kvp.Value.TryGetTarget(out v))
                    {
                        deadGuids.Add(kvp.Key);
                    }

                    if (!_parent._valueComparer.Equals(v, value))
                    {
                        continue;
                    }
                    deadGuids.Add(kvp.Key);
                    found = true;
                    break;
                }
                foreach (Guid guid in deadGuids)
                {
                    WeakReference <TValue> weakReference;
                    if (!_dictionary.TryRemove(guid, out weakReference) ||
                        (weakReference == null))
                    {
                        continue;
                    }
                    ObservableWeakReference <TValue> owf = weakReference as ObservableWeakReference <TValue>;
                    if (owf != null)
                    {
                        owf.Dispose();
                    }
                }

                // If we're down to one remove grouping.
                if (_dictionary.Count < 1)
                {
                    WeakGrouping weakGrouping;
                    _parent._dictionary.TryRemove(Key, out weakGrouping);
                }
                return(found);
            }
        /// <summary>
        ///   Wraps the specified value in a weak reference.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="value">The value.</param>
        /// <param name="register">If set to <see langword="true"/> registers the finalize event immediately.</param>
        /// <returns>The wrapped value.</returns>
        private WeakReference <TValue> Wrap([NotNull] TKey key, [CanBeNull] TValue value, bool register = true)
        {
            if (value == null)
            {
                return(null);
            }

            if (!_observable)
            {
                return(new WeakReference <TValue>(value, _allowResurrection));
            }
            ObservableWeakReference <TValue> owf = new ObservableWeakReference <TValue>(value, _allowResurrection);

            if (register)
            {
                RegisterFinalize(key, owf);
            }
            return(owf);
        }
예제 #5
0
            /// <summary>
            ///   Adds the specified value to the group.
            /// </summary>
            /// <param name="value">The value to add.</param>
            /// <returns>The new <paramref name="value"/> added to the group.</returns>
            public WeakGrouping Add([NotNull] TValue value)
            {
                Guid guid = Guid.NewGuid();
                WeakReference <TValue> weakReference;

                if (_parent._observable)
                {
                    ObservableWeakReference <TValue> owf = new ObservableWeakReference <TValue>(
                        value,
                        _parent._allowResurrection);
                    owf.Finalized += (s, e) =>
                    {
                        WeakReference <TValue> removedValue;
                        _dictionary.TryRemove(guid, out removedValue);
                        owf.Dispose();
                    };
                    weakReference = owf;
                }
                else
                {
                    weakReference = new WeakReference <TValue>(value, _parent._allowResurrection);
                }
                _dictionary.AddOrUpdate(
                    guid,
                    g => weakReference,
                    (g, w) =>
                {
                    if ((_parent._observable) &&
                        (w != null))
                    {
                        ObservableWeakReference <TValue> o =
                            w as ObservableWeakReference <TValue>;
                        if (o != null)
                        {
                            o.Dispose();
                        }
                    }
                    return(weakReference);
                });
                return(this);
            }