From 6b6ddaaeeb949ac76e632e1bb2f2caf238ebf6ab Mon Sep 17 00:00:00 2001 From: Christian Lindenau Date: Tue, 18 Aug 2026 21:00:00 +0800 Subject: [PATCH] Apply changes from https://github.com/dotnet/wpf/pull/11179 Source-PR: https://github.com/dotnet/wpf/pull/11179 Source-Head-SHA: 58a1db84d4248b053b2efddca685803001b969ad --- .../System/Windows/DependentList.cs | 490 +++++++++--------- 1 file changed, 245 insertions(+), 245 deletions(-) diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/DependentList.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/DependentList.cs index 8c28af6a1..479998a44 100644 --- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/DependentList.cs +++ b/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/DependentList.cs @@ -1,251 +1,251 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using MS.Utility; -using MS.Internal; - -namespace System.Windows -{ - // - // The list of Dependents that depend on a Source[ID] - // - // Steps are taken to guard against list corruption due to re-entrancy when - // the Invalidation callbacks call Add / Remove. But multi-threaded - // access is not expected and so locks are not used. - // - internal class DependentList: MS.Utility.FrugalObjectList +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using MS.Utility; +using MS.Internal; + +namespace System.Windows +{ + // + // The list of Dependents that depend on a Source[ID] + // + // Steps are taken to guard against list corruption due to re-entrancy when + // the Invalidation callbacks call Add / Remove. But multi-threaded + // access is not expected and so locks are not used. + // + internal class DependentList: MS.Utility.FrugalObjectList + { + public void Add(DependencyObject d, DependencyProperty dp, Expression expr) + { + // don't clean up every time. This would make Add() cost O(N), + // which would cause building a list to cost O(N^2). yuck! + // Clean the list less often the longer it gets. + if(Count == Capacity) + CleanUpDeadWeakReferences(); + + Dependent dep = new Dependent(d, dp, expr); + base.Add(dep); + } + + public void Remove(DependencyObject d, DependencyProperty dp, Expression expr) + { + Dependent dep = new Dependent(d, dp, expr); + base.Remove(dep); + } + + public bool IsEmpty + { + get + { + for(int i = Count-1; i >= 0; i--) + { + if(this[i].IsValid()) + { + return false; + } + } + + // there are no valid entries. All callers immediately discard the + // empty DependentList in this case, so there's no need to clean out + // the list. We can just GC collect the WeakReferences. + return true; + } + } + + public void InvalidateDependents(DependencyObject source, DependencyPropertyChangedEventArgs sourceArgs) + { + // Take a snapshot of the list to protect against re-entrancy via Add / Remove. + Dependent[] snapList = base.ToArray(); + + for(int i=0; i=0; --i) + { + if (this[i].IsValid()) + { + ++ newCount; + } + } + + // if all the entries are valid, there's nothing to do + if (newCount == Count) + return; + + // compact the valid entries + Compacter compacter = new Compacter(this, newCount); + int runStart = 0; // starting index of current run + bool runIsValid = false; // whether run contains valid or invalid entries + + for (int i=0, n=Count; i { - public void Add(DependencyObject d, DependencyProperty dp, Expression expr) - { - // don't clean up every time. This would make Add() cost O(N), - // which would cause building a list to cost O(N^2). yuck! - // Clean the list less often the longer it gets. - if(Count == Capacity) - CleanUpDeadWeakReferences(); - - Dependent dep = new Dependent(d, dp, expr); - base.Add(dep); - } - - public void Remove(DependencyObject d, DependencyProperty dp, Expression expr) - { - Dependent dep = new Dependent(d, dp, expr); - base.Remove(dep); - } - - public bool IsEmpty - { - get - { - for(int i = Count-1; i >= 0; i--) - { - if(this[i].IsValid()) - { - return false; - } - } - - // there are no valid entries. All callers immediately discard the - // empty DependentList in this case, so there's no need to clean out - // the list. We can just GC collect the WeakReferences. - return true; - } - } - - public void InvalidateDependents(DependencyObject source, DependencyPropertyChangedEventArgs sourceArgs) - { - // Take a snapshot of the list to protect against re-entrancy via Add / Remove. - Dependent[] snapList = base.ToArray(); - - for(int i=0; i=0; --i) - { - if (this[i].IsValid()) - { - ++ newCount; - } - } - - // if all the entries are valid, there's nothing to do - if (newCount == Count) - return; - - // compact the valid entries - Compacter compacter = new Compacter(this, newCount); - int runStart = 0; // starting index of current run - bool runIsValid = false; // whether run contains valid or invalid entries - - for (int i=0, n=Count; i