using System.Collections.Concurrent;
using System.IO;
using System.Windows;
using System.Windows.Media;
namespace DeskCore;
/// Lädt Icons auf einem eigenen STA-Thread (Shell-COM braucht STA) und cached sie.
public static class IconLoader
{
private static readonly ConcurrentDictionary _cache = new(StringComparer.OrdinalIgnoreCase);
private static readonly BlockingCollection<(IconItem Item, int Size)> _queue = new();
static IconLoader()
{
var t = new Thread(Work) { IsBackground = true, Name = "IconLoader" };
t.SetApartmentState(ApartmentState.STA);
t.Start();
}
private static string Key(string path, int size)
{
DateTime stamp;
try { stamp = File.GetLastWriteTimeUtc(path); } catch { stamp = default; }
return $"{size}|{stamp.Ticks}|{path}";
}
/// Setzt das Icon sofort aus dem Cache oder lädt es im Hintergrund nach.
public static void Load(IconItem item, int size)
{
if (_cache.TryGetValue(Key(item.Path, size), out var icon)) item.Icon = icon;
else _queue.Add((item, size));
}
private static void Work()
{
foreach (var (item, size) in _queue.GetConsumingEnumerable())
{
var key = Key(item.Path, size);
if (!_cache.TryGetValue(key, out var icon))
{
icon = ShellIcon.Get(item.Path, size);
_cache[key] = icon;
}
var result = icon;
Application.Current?.Dispatcher.BeginInvoke(() => item.Icon = result);
}
}
}