From 5e2d17b02b746a864f215beff77e74872fd7577a Mon Sep 17 00:00:00 2001 From: Peter Kirmeier Date: Sat, 23 Sep 2023 12:18:01 +0200 Subject: [PATCH] Improve sub menu loading performance Use thread pool for background icon loading. This eliminates massive thread spawns on very large folders. --- Utilities/File/IconReader.cs | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/Utilities/File/IconReader.cs b/Utilities/File/IconReader.cs index 01974e4..d356d9d 100644 --- a/Utilities/File/IconReader.cs +++ b/Utilities/File/IconReader.cs @@ -23,9 +23,32 @@ namespace SystemTrayMenu.Utilities /// internal static class IconReader { + private static readonly BitmapSource? OverlayImage = (BitmapSource?)Application.Current.Resources["LinkArrowIconImage"]; + private static readonly ConcurrentDictionary IconDictPersistent = new(); private static readonly ConcurrentDictionary IconDictCache = new(); - private static readonly BitmapSource? OverlayImage = (BitmapSource?)Application.Current.Resources["LinkArrowIconImage"]; + private static readonly BlockingCollection IconFactoryQueue = new(); + private static readonly List IconFactoryThreadPoolSTA = new(16); + + static IconReader() + { + for (int i = 0; i < IconFactoryThreadPoolSTA.Capacity; i++) + { + Thread thread = new(IconFactoryWorkerSTA); + thread.Name = "IconFactory STA #" + i.ToString(); + thread.SetApartmentState(ApartmentState.STA); + thread.Start(); + IconFactoryThreadPoolSTA.Add(thread); + } + + void IconFactoryWorkerSTA() + { + while(true) + { + IconFactoryQueue.Take()(); + } + } + } internal static void ClearCacheWhenLimitReached() { @@ -110,14 +133,11 @@ namespace SystemTrayMenu.Utilities } else { - Thread thread = new(UpdateIconInBackgroundSTA); - thread.SetApartmentState(ApartmentState.STA); - thread.Start(); - void UpdateIconInBackgroundSTA() + IconFactoryQueue.Add(() => { BitmapSource icon = DictIconCache(checkPersistentFirst).GetOrAdd(key, factory); onIconLoaded(icon); - } + }); return false; }