@@ -27,6 +27,9 @@ public class Main : ISettingProvider, IAsyncPlugin, IPluginI18n, IContextMenu, I
27
27
internal static List < UWPApp > _uwps { get ; private set ; }
28
28
internal static Settings _settings { get ; private set ; }
29
29
30
+ internal static SemaphoreSlim _win32sLock = new ( 1 , 1 ) ;
31
+ internal static SemaphoreSlim _uwpsLock = new ( 1 , 1 ) ;
32
+
30
33
internal static PluginInitContext Context { get ; private set ; }
31
34
32
35
private static readonly List < Result > emptyResults = new ( ) ;
@@ -82,8 +85,11 @@ public async Task<List<Result>> QueryAsync(Query query, CancellationToken token)
82
85
{
83
86
var result = await cache . GetOrCreateAsync ( query . Search , async entry =>
84
87
{
85
- var resultList = await Task . Run ( ( ) =>
88
+ var resultList = await Task . Run ( async ( ) =>
86
89
{
90
+ await _win32sLock . WaitAsync ( token ) ;
91
+ await _uwpsLock . WaitAsync ( token ) ;
92
+
87
93
try
88
94
{
89
95
// Collect all UWP Windows app directories
@@ -95,22 +101,26 @@ public async Task<List<Result>> QueryAsync(Query query, CancellationToken token)
95
101
. ToArray ( ) : null ;
96
102
97
103
return _win32s . Cast < IProgram > ( )
98
- . Concat ( _uwps )
99
- . AsParallel ( )
100
- . WithCancellation ( token )
101
- . Where ( HideUninstallersFilter )
102
- . Where ( p => HideDuplicatedWindowsAppFilter ( p , uwpsDirectories ) )
103
- . Where ( p => p . Enabled )
104
- . Select ( p => p . Result ( query . Search , Context . API ) )
105
- . Where ( r => r ? . Score > 0 )
106
- . ToList ( ) ;
104
+ . Concat ( _uwps )
105
+ . AsParallel ( )
106
+ . WithCancellation ( token )
107
+ . Where ( HideUninstallersFilter )
108
+ . Where ( p => HideDuplicatedWindowsAppFilter ( p , uwpsDirectories ) )
109
+ . Where ( p => p . Enabled )
110
+ . Select ( p => p . Result ( query . Search , Context . API ) )
111
+ . Where ( r => r ? . Score > 0 )
112
+ . ToList ( ) ;
107
113
}
108
114
catch ( OperationCanceledException )
109
115
{
110
116
Log . Debug ( "|Flow.Launcher.Plugin.Program.Main|Query operation cancelled" ) ;
111
117
return emptyResults ;
112
118
}
113
-
119
+ finally
120
+ {
121
+ _uwpsLock . Release ( ) ;
122
+ _win32sLock . Release ( ) ;
123
+ }
114
124
} , token ) ;
115
125
116
126
resultList = resultList . Any ( ) ? resultList : emptyResults ;
@@ -236,14 +246,25 @@ static void MoveFile(string sourcePath, string destinationPath)
236
246
var newUWPCacheFile = Path . Combine ( pluginCachePath , $ "{ UwpCacheName } .cache") ;
237
247
MoveFile ( oldUWPCacheFile , newUWPCacheFile ) ;
238
248
249
+ await _win32sLock . WaitAsync ( ) ;
239
250
_win32s = await context . API . LoadCacheBinaryStorageAsync ( Win32CacheName , pluginCachePath , new List < Win32 > ( ) ) ;
251
+ _win32sLock . Release ( ) ;
252
+
253
+ await _uwpsLock . WaitAsync ( ) ;
240
254
_uwps = await context . API . LoadCacheBinaryStorageAsync ( UwpCacheName , pluginCachePath , new List < UWPApp > ( ) ) ;
255
+ _uwpsLock . Release ( ) ;
241
256
} ) ;
257
+ await _win32sLock . WaitAsync ( ) ;
258
+ await _uwpsLock . WaitAsync ( ) ;
259
+
242
260
Log . Info ( $ "|Flow.Launcher.Plugin.Program.Main|Number of preload win32 programs <{ _win32s . Count } >") ;
243
261
Log . Info ( $ "|Flow.Launcher.Plugin.Program.Main|Number of preload uwps <{ _uwps . Count } >") ;
244
262
245
263
bool cacheEmpty = ! _win32s . Any ( ) || ! _uwps . Any ( ) ;
246
264
265
+ _win32sLock . Release ( ) ;
266
+ _uwpsLock . Release ( ) ;
267
+
247
268
if ( cacheEmpty || _settings . LastIndexTime . AddHours ( 30 ) < DateTime . Now )
248
269
{
249
270
_ = Task . Run ( async ( ) =>
@@ -267,11 +288,13 @@ static void WatchProgramUpdate()
267
288
public static async Task IndexWin32ProgramsAsync ( )
268
289
{
269
290
var win32S = Win32 . All ( _settings ) ;
291
+ await _win32sLock . WaitAsync ( ) ;
270
292
_win32s . Clear ( ) ;
271
293
foreach ( var win32 in win32S )
272
294
{
273
295
_win32s . Add ( win32 ) ;
274
296
}
297
+ _win32sLock . Release ( ) ;
275
298
ResetCache ( ) ;
276
299
await Context . API . SaveCacheBinaryStorageAsync < List < Win32 > > ( Win32CacheName , Context . CurrentPluginMetadata . PluginCacheDirectoryPath ) ;
277
300
_settings . LastIndexTime = DateTime . Now ;
@@ -280,11 +303,13 @@ public static async Task IndexWin32ProgramsAsync()
280
303
public static async Task IndexUwpProgramsAsync ( )
281
304
{
282
305
var uwps = UWPPackage . All ( _settings ) ;
306
+ await _uwpsLock . WaitAsync ( ) ;
283
307
_uwps . Clear ( ) ;
284
308
foreach ( var uwp in uwps )
285
309
{
286
310
_uwps . Add ( uwp ) ;
287
311
}
312
+ _uwpsLock . Release ( ) ;
288
313
ResetCache ( ) ;
289
314
await Context . API . SaveCacheBinaryStorageAsync < List < UWPApp > > ( UwpCacheName , Context . CurrentPluginMetadata . PluginCacheDirectoryPath ) ;
290
315
_settings . LastIndexTime = DateTime . Now ;
@@ -358,26 +383,36 @@ public List<Result> LoadContextMenus(Result selectedResult)
358
383
return menuOptions ;
359
384
}
360
385
361
- private static void DisableProgram ( IProgram programToDelete )
386
+ private static async Task DisableProgram ( IProgram programToDelete )
362
387
{
363
388
if ( _settings . DisabledProgramSources . Any ( x => x . UniqueIdentifier == programToDelete . UniqueIdentifier ) )
364
389
return ;
365
390
391
+ await _uwpsLock . WaitAsync ( ) ;
366
392
if ( _uwps . Any ( x => x . UniqueIdentifier == programToDelete . UniqueIdentifier ) )
367
393
{
368
394
var program = _uwps . First ( x => x . UniqueIdentifier == programToDelete . UniqueIdentifier ) ;
369
395
program . Enabled = false ;
370
396
_settings . DisabledProgramSources . Add ( new ProgramSource ( program ) ) ;
397
+ _uwpsLock . Release ( ) ;
398
+
399
+ // Reindex UWP programs
371
400
_ = Task . Run ( ( ) =>
372
401
{
373
402
_ = IndexUwpProgramsAsync ( ) ;
374
403
} ) ;
404
+ return ;
375
405
}
376
- else if ( _win32s . Any ( x => x . UniqueIdentifier == programToDelete . UniqueIdentifier ) )
406
+
407
+ await _win32sLock . WaitAsync ( ) ;
408
+ if ( _win32s . Any ( x => x . UniqueIdentifier == programToDelete . UniqueIdentifier ) )
377
409
{
378
410
var program = _win32s . First ( x => x . UniqueIdentifier == programToDelete . UniqueIdentifier ) ;
379
411
program . Enabled = false ;
380
412
_settings . DisabledProgramSources . Add ( new ProgramSource ( program ) ) ;
413
+ _win32sLock . Release ( ) ;
414
+
415
+ // Reindex Win32 programs
381
416
_ = Task . Run ( ( ) =>
382
417
{
383
418
_ = IndexWin32ProgramsAsync ( ) ;
0 commit comments