mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Merge pull request #4072 from Flow-Launcher/program_plugin_index_issue
Fix Possible OperationCancelException for WaitAsync Operations
This commit is contained in:
commit
fc93d0904e
3 changed files with 82 additions and 19 deletions
|
|
@ -26,9 +26,11 @@ namespace Flow.Launcher.Core.ExternalPlugins
|
|||
|
||||
public static async Task<bool> UpdateManifestAsync(bool usePrimaryUrlOnly = false, CancellationToken token = default)
|
||||
{
|
||||
bool lockAcquired = false;
|
||||
try
|
||||
{
|
||||
await manifestUpdateLock.WaitAsync(token).ConfigureAwait(false);
|
||||
lockAcquired = true;
|
||||
|
||||
if (UserPlugins == null || usePrimaryUrlOnly || DateTime.Now.Subtract(lastFetchedAt) >= fetchTimeout)
|
||||
{
|
||||
|
|
@ -54,13 +56,18 @@ namespace Flow.Launcher.Core.ExternalPlugins
|
|||
return true;
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
// Ignored
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
PublicApi.Instance.LogException(ClassName, "Http request failed", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
manifestUpdateLock.Release();
|
||||
// Only release the lock if it was acquired
|
||||
if (lockAcquired) manifestUpdateLock.Release();
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -48,11 +48,18 @@ namespace Flow.Launcher.Plugin.Explorer.Search.Everything
|
|||
|
||||
public static async ValueTask<bool> IsEverythingRunningAsync(CancellationToken token = default)
|
||||
{
|
||||
await _semaphore.WaitAsync(token);
|
||||
try
|
||||
{
|
||||
await _semaphore.WaitAsync(token);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
EverythingApiDllImport.Everything_GetMajorVersion();
|
||||
_ = EverythingApiDllImport.Everything_GetMajorVersion();
|
||||
var result = EverythingApiDllImport.Everything_GetLastError() != StateCode.IPCError;
|
||||
return result;
|
||||
}
|
||||
|
|
@ -77,8 +84,14 @@ namespace Flow.Launcher.Plugin.Explorer.Search.Everything
|
|||
if (option.MaxCount < 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(option.MaxCount), option.MaxCount, "MaxCount must be greater than or equal to 0");
|
||||
|
||||
await _semaphore.WaitAsync(token);
|
||||
|
||||
try
|
||||
{
|
||||
await _semaphore.WaitAsync(token);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
|
|
@ -120,8 +133,6 @@ namespace Flow.Launcher.Plugin.Explorer.Search.Everything
|
|||
EverythingApiDllImport.Everything_SetRequestFlags(EVERYTHING_REQUEST_FULL_PATH_AND_FILE_NAME);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (token.IsCancellationRequested) yield break;
|
||||
|
||||
if (!EverythingApiDllImport.Everything_QueryW(true))
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@ namespace Flow.Launcher.Plugin.Program
|
|||
|
||||
internal static PluginInitContext Context { get; private set; }
|
||||
|
||||
private static readonly Lock _lastIndexTimeLock = new();
|
||||
|
||||
private static readonly List<Result> emptyResults = [];
|
||||
|
||||
private static readonly MemoryCacheOptions cacheOptions = new() { SizeLimit = 1560 };
|
||||
|
|
@ -82,8 +84,45 @@ namespace Flow.Launcher.Plugin.Program
|
|||
{
|
||||
var resultList = await Task.Run(async () =>
|
||||
{
|
||||
await _win32sLock.WaitAsync(token);
|
||||
await _uwpsLock.WaitAsync(token);
|
||||
// Preparing win32 programs
|
||||
List<Win32> win32s;
|
||||
bool win32LockAcquired = false;
|
||||
try
|
||||
{
|
||||
await _win32sLock.WaitAsync(token);
|
||||
win32LockAcquired = true;
|
||||
win32s = [.. _win32s];
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
return emptyResults;
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Only release the lock if it was acquired
|
||||
if (win32LockAcquired) _win32sLock.Release();
|
||||
}
|
||||
|
||||
// Preparing UWP programs
|
||||
List<UWPApp> uwps;
|
||||
bool uwpsLockAcquired = false;
|
||||
try
|
||||
{
|
||||
await _uwpsLock.WaitAsync(token);
|
||||
uwpsLockAcquired = true;
|
||||
uwps = [.. _uwps];
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
return emptyResults;
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Only release the lock if it was acquired
|
||||
if (uwpsLockAcquired) _uwpsLock.Release();
|
||||
}
|
||||
|
||||
// Start querying programs
|
||||
try
|
||||
{
|
||||
// Collect all UWP Windows app directories
|
||||
|
|
@ -94,8 +133,8 @@ namespace Flow.Launcher.Plugin.Program
|
|||
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||
.ToArray() : null;
|
||||
|
||||
return _win32s.Cast<IProgram>()
|
||||
.Concat(_uwps)
|
||||
return win32s.Cast<IProgram>()
|
||||
.Concat(uwps)
|
||||
.AsParallel()
|
||||
.WithCancellation(token)
|
||||
.Where(HideUninstallersFilter)
|
||||
|
|
@ -109,11 +148,6 @@ namespace Flow.Launcher.Plugin.Program
|
|||
{
|
||||
return emptyResults;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_uwpsLock.Release();
|
||||
_win32sLock.Release();
|
||||
}
|
||||
}, token);
|
||||
|
||||
resultList = resultList.Count != 0 ? resultList : emptyResults;
|
||||
|
|
@ -275,7 +309,12 @@ namespace Flow.Launcher.Plugin.Program
|
|||
|
||||
var cacheEmpty = _win32sCount == 0 || _uwpsCount == 0;
|
||||
|
||||
if (cacheEmpty || _settings.LastIndexTime.AddHours(30) < DateTime.Now)
|
||||
bool needReindex;
|
||||
lock (_lastIndexTimeLock)
|
||||
{
|
||||
needReindex = _settings.LastIndexTime.AddHours(30) < DateTime.Now;
|
||||
}
|
||||
if (cacheEmpty || needReindex)
|
||||
{
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
|
|
@ -308,7 +347,10 @@ namespace Flow.Launcher.Plugin.Program
|
|||
}
|
||||
ResetCache();
|
||||
await Context.API.SaveCacheBinaryStorageAsync<List<Win32>>(Win32CacheName, Context.CurrentPluginMetadata.PluginCacheDirectoryPath);
|
||||
_settings.LastIndexTime = DateTime.Now;
|
||||
lock (_lastIndexTimeLock)
|
||||
{
|
||||
_settings.LastIndexTime = DateTime.Now;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
|
@ -333,7 +375,10 @@ namespace Flow.Launcher.Plugin.Program
|
|||
}
|
||||
ResetCache();
|
||||
await Context.API.SaveCacheBinaryStorageAsync<List<UWPApp>>(UwpCacheName, Context.CurrentPluginMetadata.PluginCacheDirectoryPath);
|
||||
_settings.LastIndexTime = DateTime.Now;
|
||||
lock (_lastIndexTimeLock)
|
||||
{
|
||||
_settings.LastIndexTime = DateTime.Now;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue