Skip to content

Commit b468a2b

Browse files
committed
Revert "Improve performance of DynamicResource usages (dotnet#5610)"
This reverts commit 38a157c.
1 parent 09f967d commit b468a2b

File tree

2 files changed

+30
-126
lines changed

2 files changed

+30
-126
lines changed

src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/ResourceDictionary.cs

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1735,31 +1735,23 @@ private object FetchResource(
17351735
DeferredResourceReference deferredResourceReference;
17361736
if (!IsThemeDictionary)
17371737
{
1738-
// Cache the deferredResourceReference so that it can be validated
1739-
// in case of a dictionary change prior to its inflation
1740-
if (_deferredResourceReferences == null)
1741-
{
1742-
_deferredResourceReferences = new DeferredResourceReferenceList();
1743-
}
1744-
1745-
if (_deferredResourceReferences.Get(resourceKey) is { } existingDeferredResourceReference
1746-
&& existingDeferredResourceReference.Dictionary == this)
1738+
if (_ownerApps != null)
17471739
{
1748-
deferredResourceReference = existingDeferredResourceReference;
1740+
deferredResourceReference = new DeferredAppResourceReference(this, resourceKey);
17491741
}
17501742
else
17511743
{
1752-
if (_ownerApps != null)
1753-
{
1754-
deferredResourceReference = new DeferredAppResourceReference(this, resourceKey);
1755-
}
1756-
else
1757-
{
1758-
deferredResourceReference = new DeferredResourceReference(this, resourceKey);
1759-
}
1744+
deferredResourceReference = new DeferredResourceReference(this, resourceKey);
1745+
}
17601746

1761-
_deferredResourceReferences.AddOrSet(deferredResourceReference);
1747+
// Cache the deferredResourceReference so that it can be validated
1748+
// in case of a dictionary change prior to its inflation
1749+
if (_deferredResourceReferences == null)
1750+
{
1751+
_deferredResourceReferences = new WeakReferenceList();
17621752
}
1753+
1754+
_deferredResourceReferences.Add( deferredResourceReference, true /*SkipFind*/);
17631755
}
17641756
else
17651757
{
@@ -1783,18 +1775,22 @@ private void ValidateDeferredResourceReferences(object resourceKey)
17831775
{
17841776
if (_deferredResourceReferences != null)
17851777
{
1786-
DeferredResourceReference deferredResourceReference = _deferredResourceReferences.Get(resourceKey);
1787-
1788-
if (deferredResourceReference is not null)
1778+
foreach (Object o in _deferredResourceReferences)
17891779
{
1790-
// This will inflate the deferred reference, causing it
1791-
// to be removed from the list. The list may also be
1792-
// purged of dead references.
1793-
deferredResourceReference.GetValue(BaseValueSourceInternal.Unknown);
1780+
1781+
DeferredResourceReference deferredResourceReference = o as DeferredResourceReference;
1782+
if (deferredResourceReference != null && (resourceKey == null || Object.Equals(resourceKey, deferredResourceReference.Key)))
1783+
{
1784+
// This will inflate the deferred reference, causing it
1785+
// to be removed from the list. The list may also be
1786+
// purged of dead references.
1787+
deferredResourceReference.GetValue(BaseValueSourceInternal.Unknown);
1788+
}
17941789
}
17951790
}
17961791
}
17971792

1793+
17981794
/// <summary>
17991795
/// Called when the MergedDictionaries collection changes
18001796
/// </summary>
@@ -2057,7 +2053,7 @@ internal WeakReferenceList ApplicationOwners
20572053

20582054
#region Properties
20592055

2060-
internal DeferredResourceReferenceList DeferredResourceReferences
2056+
internal WeakReferenceList DeferredResourceReferences
20612057
{
20622058
get { return _deferredResourceReferences; }
20632059
}
@@ -2482,7 +2478,10 @@ private void MoveDeferredResourceReferencesFrom(ResourceDictionary loadedRD)
24822478
// redirect each entry toward its new owner
24832479
if (_deferredResourceReferences != null)
24842480
{
2485-
_deferredResourceReferences.ChangeDictionary(this);
2481+
foreach (DeferredResourceReference drr in _deferredResourceReferences)
2482+
{
2483+
drr.Dictionary = this;
2484+
}
24862485
}
24872486
}
24882487

@@ -2549,7 +2548,7 @@ private enum FallbackState
25492548
private WeakReferenceList _ownerFEs = null;
25502549
private WeakReferenceList _ownerFCEs = null;
25512550
private WeakReferenceList _ownerApps = null;
2552-
private DeferredResourceReferenceList _deferredResourceReferences = null;
2551+
private WeakReferenceList _deferredResourceReferences = null;
25532552
private ObservableCollection<ResourceDictionary> _mergedDictionaries = null;
25542553
private Uri _source = null;
25552554
private Uri _baseUri = null;

src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/SystemResources.cs

Lines changed: 2 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -1745,9 +1745,8 @@ internal override object GetValue(BaseValueSourceInternal valueSource)
17451745
{
17461746
// Note that we are replacing the _keyorValue field
17471747
// with the value and deleting the _dictionary field.
1748-
RemoveFromDictionary();
1749-
// Update after removal from dictionary as we need the key for proper removal
17501748
_keyOrValue = value;
1749+
RemoveFromDictionary();
17511750
}
17521751

17531752
// Freeze if this value originated from a style or template
@@ -2039,103 +2038,9 @@ internal override bool IsUnset
20392038

20402039
#endregion Properties
20412040
}
2041+
}
20422042

2043-
internal class DeferredResourceReferenceList
2044-
{
2045-
private readonly object _syncRoot = new();
2046-
private readonly Dictionary<object, WeakReference<DeferredResourceReference>> _entries = new();
2047-
private int _potentiallyDeadEntryCount = 0;
2048-
2049-
public void AddOrSet(DeferredResourceReference deferredResourceReference)
2050-
{
2051-
lock (_syncRoot)
2052-
{
2053-
_entries[deferredResourceReference.Key] = new WeakReference<DeferredResourceReference>(deferredResourceReference);
2054-
}
2055-
}
2056-
2057-
public void Remove(DeferredResourceReference deferredResourceReference)
2058-
{
2059-
lock (_syncRoot)
2060-
{
2061-
_entries.Remove(deferredResourceReference.Key);
2062-
}
2063-
}
2064-
2065-
internal DeferredResourceReference Get(object resourceKey)
2066-
{
2067-
lock (_syncRoot)
2068-
{
2069-
_entries.TryGetValue(resourceKey, out var weakReference);
2070-
2071-
if (weakReference is null)
2072-
{
2073-
return null;
2074-
}
2075-
2076-
if (weakReference.TryGetTarget(out var deferredResourceReference))
2077-
{
2078-
return deferredResourceReference;
2079-
}
2080-
else
2081-
{
2082-
++_potentiallyDeadEntryCount;
2083-
}
2084-
}
2085-
2086-
PurgeIfRequired();
2087-
2088-
return null;
2089-
}
2090-
2091-
internal void ChangeDictionary(ResourceDictionary resourceDictionary)
2092-
{
2093-
lock (_syncRoot)
2094-
{
2095-
foreach (WeakReference<DeferredResourceReference> weakReference in _entries.Values)
2096-
{
2097-
if (weakReference.TryGetTarget(out var deferredResourceReference))
2098-
{
2099-
deferredResourceReference.Dictionary = resourceDictionary;
2100-
}
2101-
else
2102-
{
2103-
++_potentiallyDeadEntryCount;
2104-
}
2105-
}
2106-
}
2107-
2108-
PurgeIfRequired();
2109-
}
21102043

2111-
private void PurgeIfRequired()
2112-
{
2113-
if (_potentiallyDeadEntryCount > 25)
2114-
{
2115-
Purge();
2116-
}
2117-
}
21182044

2119-
private void Purge()
2120-
{
2121-
lock (_syncRoot)
2122-
{
2123-
List<object> deadKeys = new(Math.Min(_potentiallyDeadEntryCount, _entries.Count));
2124-
_potentiallyDeadEntryCount = 0;
21252045

2126-
foreach (KeyValuePair<object, WeakReference<DeferredResourceReference>> entry in _entries)
2127-
{
2128-
if (entry.Value.TryGetTarget(out _) == false)
2129-
{
2130-
deadKeys.Add(entry.Key);
2131-
}
2132-
}
21332046

2134-
foreach (object deadKey in deadKeys)
2135-
{
2136-
_entries.Remove(deadKey);
2137-
}
2138-
}
2139-
}
2140-
}
2141-
}

0 commit comments

Comments
 (0)