Skip to content

Commit a083528

Browse files
committed
Use SemaphoreSlim to ensure cache only remove once
1 parent 710d2a8 commit a083528

File tree

1 file changed

+17
-10
lines changed

1 file changed

+17
-10
lines changed

Flow.Launcher.Infrastructure/Image/ImageCache.cs

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Concurrent;
33
using System.Collections.Generic;
44
using System.Linq;
5+
using System.Threading;
56
using System.Threading.Tasks;
67
using System.Windows.Media;
78

@@ -26,6 +27,7 @@ public class ImageCache
2627
private const int MaxCached = 50;
2728
public ConcurrentDictionary<string, ImageUsage> Data { get; private set; } = new ConcurrentDictionary<string, ImageUsage>();
2829
private const int permissibleFactor = 2;
30+
private SemaphoreSlim semaphore = new(1, 1);
2931

3032
public void Initialization(Dictionary<string, int> usage)
3133
{
@@ -35,8 +37,6 @@ public void Initialization(Dictionary<string, int> usage)
3537
}
3638
}
3739

38-
private volatile bool removing;
39-
4040
public ImageSource this[string path]
4141
{
4242
get
@@ -62,15 +62,22 @@ public ImageSource this[string path]
6262
}
6363
);
6464

65-
// To prevent the dictionary from drastically increasing in size by caching images, the dictionary size is not allowed to grow more than the permissibleFactor * maxCached size
66-
// This is done so that we don't constantly perform this resizing operation and also maintain the image cache size at the same time
67-
if (Data.Count > permissibleFactor * MaxCached && !removing)
65+
SliceExtra();
66+
67+
async void SliceExtra()
6868
{
69-
removing = true;
70-
// To delete the images from the data dictionary based on the resizing of the Usage Dictionary.
71-
foreach (var key in Data.OrderBy(x => x.Value.usage).Take(Data.Count - MaxCached).Select(x => x.Key))
72-
Data.TryRemove(key, out _);
73-
removing = false;
69+
// To prevent the dictionary from drastically increasing in size by caching images, the dictionary size is not allowed to grow more than the permissibleFactor * maxCached size
70+
// This is done so that we don't constantly perform this resizing operation and also maintain the image cache size at the same time
71+
if (Data.Count > permissibleFactor * MaxCached)
72+
{
73+
await semaphore.WaitAsync();
74+
// To delete the images from the data dictionary based on the resizing of the Usage Dictionary
75+
// Double Check to avoid concurrent remove
76+
if (Data.Count > permissibleFactor * MaxCached)
77+
foreach (var key in Data.OrderBy(x => x.Value.usage).Take(Data.Count - MaxCached).Select(x => x.Key).ToArray())
78+
Data.TryRemove(key, out _);
79+
semaphore.Release();
80+
}
7481
}
7582
}
7683
}

0 commit comments

Comments
 (0)