Make locking operations cancelable with tokens

Updated `_semaphore.WaitAsync` in `EverythingAPI.cs` to accept a `CancellationToken` and handle `OperationCanceledException` gracefully, returning `false` instead of propagating the exception.

Refactored locking mechanisms in `Main.cs` to use `CancellationToken` for `_win32sLock` and `_uwpsLock`. Added `try-catch` blocks to handle `OperationCanceledException` and ensure proper lock release. Methods now return `emptyResults` when operations are canceled.
This commit is contained in:
Jack251970 2025-11-06 20:46:29 +08:00
parent d0a47c84b9
commit 49f89e33b5
2 changed files with 16 additions and 16 deletions

View file

@ -48,13 +48,17 @@ namespace Flow.Launcher.Plugin.Explorer.Search.Everything
public static async ValueTask<bool> IsEverythingRunningAsync(CancellationToken token = default)
{
// We do not directly pass token here, but we check IsCancellationRequested inside the lock
// So that it will not raise OperationCanceledException, which is not expected by the caller.
await _semaphore.WaitAsync();
try
{
await _semaphore.WaitAsync(token);
}
catch (OperationCanceledException)
{
return false;
}
try
{
if (token.IsCancellationRequested) return false;
_ = EverythingApiDllImport.Everything_GetMajorVersion();
var result = EverythingApiDllImport.Everything_GetLastError() != StateCode.IPCError;
return result;

View file

@ -84,35 +84,31 @@ namespace Flow.Launcher.Plugin.Program
{
var resultList = await Task.Run(async () =>
{
// We do not directly pass token here, but we check IsCancellationRequested inside the lock
// So that it will not raise OperationCanceledException, which is not expected by the caller.
Context.API.LogDebug(ClassName, "Preparing win32 programs");
List<Win32> win32s;
await _win32sLock.WaitAsync();
try
{
await _win32sLock.WaitAsync(token);
win32s = [.. _win32s];
if (token.IsCancellationRequested) return emptyResults;
}
finally
catch (OperationCanceledException)
{
_win32sLock.Release();
return emptyResults;
}
_win32sLock.Release();
// We do not directly pass token here, but we check IsCancellationRequested inside the lock
// So that it will not raise OperationCanceledException, which is not expected by the caller.
Context.API.LogDebug(ClassName, "Preparing UWP programs");
List<UWPApp> uwps;
await _uwpsLock.WaitAsync();
try
{
await _uwpsLock.WaitAsync(token);
uwps = [.. _uwps];
if (token.IsCancellationRequested) return emptyResults;
}
finally
catch (OperationCanceledException)
{
_uwpsLock.Release();
return emptyResults;
}
_uwpsLock.Release();
Context.API.LogDebug(ClassName, "Start querying programs");
try