Merge pull request #3978 from Flow-Launcher/program_locks

Fix program lock waiting issue
This commit is contained in:
Jack Ye 2025-09-18 20:38:15 +08:00 committed by GitHub
commit 16895716e9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 79 additions and 36 deletions

View file

@ -31,7 +31,7 @@ namespace Flow.Launcher.Plugin.Program
internal static PluginInitContext Context { get; private set; }
private static readonly List<Result> emptyResults = new();
private static readonly List<Result> emptyResults = [];
private static readonly MemoryCacheOptions cacheOptions = new() { SizeLimit = 1560 };
private static MemoryCache cache = new(cacheOptions);
@ -84,7 +84,6 @@ namespace Flow.Launcher.Plugin.Program
{
await _win32sLock.WaitAsync(token);
await _uwpsLock.WaitAsync(token);
try
{
// Collect all UWP Windows app directories
@ -117,7 +116,7 @@ namespace Flow.Launcher.Plugin.Program
}
}, token);
resultList = resultList.Any() ? resultList : emptyResults;
resultList = resultList.Count != 0 ? resultList : emptyResults;
entry.SetSize(resultList.Count);
entry.SetSlidingExpiration(TimeSpan.FromHours(8));
@ -250,14 +249,26 @@ namespace Flow.Launcher.Plugin.Program
}
await _win32sLock.WaitAsync();
_win32s = await context.API.LoadCacheBinaryStorageAsync(Win32CacheName, pluginCacheDirectory, new List<Win32>());
_win32sCount = _win32s.Count;
_win32sLock.Release();
try
{
_win32s = await context.API.LoadCacheBinaryStorageAsync(Win32CacheName, pluginCacheDirectory, new List<Win32>());
_win32sCount = _win32s.Count;
}
finally
{
_win32sLock.Release();
}
await _uwpsLock.WaitAsync();
_uwps = await context.API.LoadCacheBinaryStorageAsync(UwpCacheName, pluginCacheDirectory, new List<UWPApp>());
_uwpsCount = _uwps.Count;
_uwpsLock.Release();
try
{
_uwps = await context.API.LoadCacheBinaryStorageAsync(UwpCacheName, pluginCacheDirectory, new List<UWPApp>());
_uwpsCount = _uwps.Count;
}
finally
{
_uwpsLock.Release();
}
});
Context.API.LogInfo(ClassName, $"Number of preload win32 programs <{_win32sCount}>");
Context.API.LogInfo(ClassName, $"Number of preload uwps <{_uwpsCount}>");
@ -408,38 +419,46 @@ namespace Flow.Launcher.Plugin.Program
return;
await _uwpsLock.WaitAsync();
if (_uwps.Any(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier))
var reindexUwps = true;
try
{
reindexUwps = _uwps.Any(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier);
var program = _uwps.First(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier);
program.Enabled = false;
_settings.DisabledProgramSources.Add(new ProgramSource(program));
}
finally
{
_uwpsLock.Release();
}
// Reindex UWP programs
// Reindex UWP programs
if (reindexUwps)
{
_ = Task.Run(IndexUwpProgramsAsync);
return;
}
else
{
_uwpsLock.Release();
}
await _win32sLock.WaitAsync();
if (_win32s.Any(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier))
var reindexWin32s = true;
try
{
reindexWin32s = _win32s.Any(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier);
var program = _win32s.First(x => x.UniqueIdentifier == programToDelete.UniqueIdentifier);
program.Enabled = false;
_settings.DisabledProgramSources.Add(new ProgramSource(program));
_win32sLock.Release();
// Reindex Win32 programs
_ = Task.Run(IndexWin32ProgramsAsync);
return;
}
else
finally
{
_win32sLock.Release();
}
// Reindex Win32 programs
if (reindexWin32s)
{
_ = Task.Run(IndexWin32ProgramsAsync);
return;
}
}
public static void StartProcess(Func<ProcessStartInfo, Process> runProcess, ProcessStartInfo info)

View file

@ -19,18 +19,30 @@ namespace Flow.Launcher.Plugin.Program.Views.Commands
internal static async Task DisplayAllProgramsAsync()
{
await Main._win32sLock.WaitAsync();
var win32 = Main._win32s
try
{
var win32 = Main._win32s
.Where(t1 => !ProgramSetting.ProgramSettingDisplayList.Any(x => x.UniqueIdentifier == t1.UniqueIdentifier))
.Select(x => new ProgramSource(x));
ProgramSetting.ProgramSettingDisplayList.AddRange(win32);
Main._win32sLock.Release();
ProgramSetting.ProgramSettingDisplayList.AddRange(win32);
}
finally
{
Main._win32sLock.Release();
}
await Main._uwpsLock.WaitAsync();
var uwp = Main._uwps
try
{
var uwp = Main._uwps
.Where(t1 => !ProgramSetting.ProgramSettingDisplayList.Any(x => x.UniqueIdentifier == t1.UniqueIdentifier))
.Select(x => new ProgramSource(x));
ProgramSetting.ProgramSettingDisplayList.AddRange(uwp);
Main._uwpsLock.Release();
ProgramSetting.ProgramSettingDisplayList.AddRange(uwp);
}
finally
{
Main._uwpsLock.Release();
}
}
internal static async Task SetProgramSourcesStatusAsync(List<ProgramSource> selectedProgramSourcesToDisable, bool status)
@ -44,24 +56,36 @@ namespace Flow.Launcher.Plugin.Program.Views.Commands
}
await Main._win32sLock.WaitAsync();
foreach (var program in Main._win32s)
try
{
if (selectedProgramSourcesToDisable.Any(x => x.UniqueIdentifier == program.UniqueIdentifier && program.Enabled != status))
foreach (var program in Main._win32s)
{
program.Enabled = status;
if (selectedProgramSourcesToDisable.Any(x => x.UniqueIdentifier == program.UniqueIdentifier && program.Enabled != status))
{
program.Enabled = status;
}
}
}
Main._win32sLock.Release();
finally
{
Main._win32sLock.Release();
}
await Main._uwpsLock.WaitAsync();
foreach (var program in Main._uwps)
try
{
if (selectedProgramSourcesToDisable.Any(x => x.UniqueIdentifier == program.UniqueIdentifier && program.Enabled != status))
foreach (var program in Main._uwps)
{
program.Enabled = status;
if (selectedProgramSourcesToDisable.Any(x => x.UniqueIdentifier == program.UniqueIdentifier && program.Enabled != status))
{
program.Enabled = status;
}
}
}
Main._uwpsLock.Release();
finally
{
Main._uwpsLock.Release();
}
}
internal static void StoreDisabledInSettings()