19
19
using Flow . Launcher . Plugin . SharedCommands ;
20
20
using Flow . Launcher . Storage ;
21
21
using Flow . Launcher . Infrastructure . Logger ;
22
+ using Microsoft . VisualStudio . Threading ;
22
23
using System . Threading . Channels ;
23
24
using ISavable = Flow . Launcher . Plugin . ISavable ;
25
+ using System . Windows . Threading ;
24
26
25
27
namespace Flow . Launcher . ViewModel
26
28
{
@@ -110,15 +112,17 @@ async Task updateAction()
110
112
}
111
113
112
114
Log . Error ( "MainViewModel" , "Unexpected ResultViewUpdate ends" ) ;
113
- } ;
115
+ }
116
+
117
+ ;
114
118
115
119
void continueAction ( Task t )
116
120
{
117
121
#if DEBUG
118
122
throw t . Exception ;
119
123
#else
120
124
Log . Error ( $ "Error happen in task dealing with viewupdate for results. { t . Exception } ") ;
121
- _resultsViewUpdateTask =
125
+ _resultsViewUpdateTask =
122
126
Task . Run ( updateAction ) . ContinueWith ( continueAction , TaskContinuationOptions . OnlyOnFaulted ) ;
123
127
#endif
124
128
}
@@ -137,7 +141,8 @@ private void RegisterResultsUpdatedEvent()
137
141
if ( ! _resultsUpdateChannelWriter . TryWrite ( new ResultsForUpdate ( e . Results , pair . Metadata , e . Query , _updateToken ) ) )
138
142
{
139
143
Log . Error ( "MainViewModel" , "Unable to add item to Result Update Queue" ) ;
140
- } ;
144
+ }
145
+ ;
141
146
}
142
147
} ;
143
148
}
@@ -237,21 +242,24 @@ private void InitializeKeyCommands()
237
242
238
243
ReloadPluginDataCommand = new RelayCommand ( _ =>
239
244
{
240
- var msg = new Msg { Owner = Application . Current . MainWindow } ;
245
+ var msg = new Msg
246
+ {
247
+ Owner = Application . Current . MainWindow
248
+ } ;
241
249
242
250
MainWindowVisibility = Visibility . Collapsed ;
243
251
244
252
PluginManager
245
- . ReloadData ( )
246
- . ContinueWith ( _ =>
247
- Application . Current . Dispatcher . Invoke ( ( ) =>
248
- {
249
- msg . Show (
250
- InternationalizationManager . Instance . GetTranslation ( "success" ) ,
251
- InternationalizationManager . Instance . GetTranslation ( "completedSuccessfully" ) ,
252
- "" ) ;
253
- } ) )
254
- . ConfigureAwait ( false ) ;
253
+ . ReloadData ( )
254
+ . ContinueWith ( _ =>
255
+ Application . Current . Dispatcher . Invoke ( ( ) =>
256
+ {
257
+ msg . Show (
258
+ InternationalizationManager . Instance . GetTranslation ( "success" ) ,
259
+ InternationalizationManager . Instance . GetTranslation ( "completedSuccessfully" ) ,
260
+ "" ) ;
261
+ } ) )
262
+ . ConfigureAwait ( false ) ;
255
263
} ) ;
256
264
}
257
265
@@ -422,7 +430,10 @@ private void QueryHistory()
422
430
Title = string . Format ( title , h . Query ) ,
423
431
SubTitle = string . Format ( time , h . ExecutedDateTime ) ,
424
432
IcoPath = "Images\\ history.png" ,
425
- OriginQuery = new Query { RawQuery = h . Query } ,
433
+ OriginQuery = new Query
434
+ {
435
+ RawQuery = h . Query
436
+ } ,
426
437
Action = _ =>
427
438
{
428
439
SelectedResults = Results ;
@@ -448,7 +459,9 @@ private void QueryHistory()
448
459
}
449
460
}
450
461
451
- private void QueryResults ( )
462
+ private readonly IReadOnlyList < Result > _emptyResult = new List < Result > ( ) ;
463
+
464
+ private async void QueryResults ( )
452
465
{
453
466
_updateSource ? . Cancel ( ) ;
454
467
@@ -478,74 +491,73 @@ private void QueryResults()
478
491
479
492
var plugins = PluginManager . ValidPluginsForQuery ( query ) ;
480
493
481
- Task . Run ( async ( ) =>
494
+ if ( query . ActionKeyword == Plugin . Query . GlobalPluginWildcardSign )
495
+ {
496
+ // Wait 45 millisecond for query change in global query
497
+ // if query changes, return so that it won't be calculated
498
+ await Task . Delay ( 45 , currentCancellationToken ) ;
499
+ if ( currentCancellationToken . IsCancellationRequested )
500
+ return ;
501
+ }
502
+
503
+ _ = Task . Delay ( 200 , currentCancellationToken ) . ContinueWith ( _ =>
504
+ {
505
+ // start the progress bar if query takes more than 200 ms and this is the current running query and it didn't finish yet
506
+ if ( ! currentCancellationToken . IsCancellationRequested && _isQueryRunning )
482
507
{
483
- if ( query . ActionKeyword == Plugin . Query . GlobalPluginWildcardSign )
484
- {
485
- // Wait 45 millisecond for query change in global query
486
- // if query changes, return so that it won't be calculated
487
- await Task . Delay ( 45 , currentCancellationToken ) ;
488
- if ( currentCancellationToken . IsCancellationRequested )
489
- return ;
490
- }
508
+ ProgressBarVisibility = Visibility . Visible ;
509
+ }
510
+ } , currentCancellationToken , TaskContinuationOptions . NotOnCanceled , TaskScheduler . Default ) ;
491
511
492
- _ = Task . Delay ( 200 , currentCancellationToken ) . ContinueWith ( _ =>
493
- {
494
- // start the progress bar if query takes more than 200 ms and this is the current running query and it didn't finish yet
495
- if ( ! currentCancellationToken . IsCancellationRequested && _isQueryRunning )
496
- {
497
- ProgressBarVisibility = Visibility . Visible ;
498
- }
499
- } , currentCancellationToken ) ;
512
+ // plugins is ICollection, meaning LINQ will get the Count and preallocate Array
500
513
501
- // plugins is ICollection, meaning LINQ will get the Count and preallocate Array
514
+ var tasks = plugins . Select ( plugin => plugin . Metadata . Disabled switch
515
+ {
516
+ false => QueryTask ( plugin ) ,
517
+ true => Task . CompletedTask
518
+ } ) . ToArray ( ) ;
502
519
503
- Task [ ] tasks = plugins . Select ( plugin => plugin . Metadata . Disabled switch
504
- {
505
- false => QueryTask ( plugin ) ,
506
- true => Task . CompletedTask
507
- } ) . ToArray ( ) ;
508
520
509
- try
510
- {
511
- // Check the code, WhenAll will translate all type of IEnumerable or Collection to Array, so make an array at first
512
- await Task . WhenAll ( tasks ) ;
513
- }
514
- catch ( OperationCanceledException )
515
- {
516
- // nothing to do here
517
- }
521
+ try
522
+ {
523
+ // Check the code, WhenAll will translate all type of IEnumerable or Collection to Array, so make an array at first
524
+ await Task . WhenAll ( tasks ) ;
525
+ }
526
+ catch ( OperationCanceledException )
527
+ {
528
+ // nothing to do here
529
+ }
518
530
519
- if ( currentCancellationToken . IsCancellationRequested )
520
- return ;
531
+ if ( currentCancellationToken . IsCancellationRequested )
532
+ return ;
521
533
522
- // this should happen once after all queries are done so progress bar should continue
523
- // until the end of all querying
524
- _isQueryRunning = false ;
525
- if ( ! currentCancellationToken . IsCancellationRequested )
526
- {
527
- // update to hidden if this is still the current query
528
- ProgressBarVisibility = Visibility . Hidden ;
529
- }
534
+ // this should happen once after all queries are done so progress bar should continue
535
+ // until the end of all querying
536
+ _isQueryRunning = false ;
537
+ if ( ! currentCancellationToken . IsCancellationRequested )
538
+ {
539
+ // update to hidden if this is still the current query
540
+ ProgressBarVisibility = Visibility . Hidden ;
541
+ }
530
542
531
- // Local function
532
- async Task QueryTask ( PluginPair plugin )
533
- {
534
- // Since it is wrapped within a Task.Run, the synchronous context is null
535
- // Task.Yield will force it to run in ThreadPool
536
- await Task . Yield ( ) ;
543
+ // Local function
544
+ async Task QueryTask ( PluginPair plugin )
545
+ {
546
+ // Since it is wrapped within a Task.Run, the synchronous context is null
547
+ // Task.Yield will force it to run in ThreadPool
548
+ await Task . Yield ( ) ;
537
549
538
- var results = await PluginManager . QueryForPlugin ( plugin , query , currentCancellationToken ) ;
539
- if ( currentCancellationToken . IsCancellationRequested || results == null ) return ;
550
+ IReadOnlyList < Result > results = await PluginManager . QueryForPluginAsync ( plugin , query , currentCancellationToken ) ;
551
+
552
+ currentCancellationToken . ThrowIfCancellationRequested ( ) ;
540
553
541
- if ( ! _resultsUpdateChannelWriter . TryWrite ( new ResultsForUpdate ( results , plugin . Metadata , query , currentCancellationToken ) ) )
542
- {
543
- Log . Error ( "MainViewModel" , "Unable to add item to Result Update Queue" ) ;
544
- } ;
545
- }
546
- } , currentCancellationToken )
547
- . ContinueWith ( t => Log . Exception ( "|MainViewModel|Plugins Query Exceptions" , t . Exception ) ,
548
- TaskContinuationOptions . OnlyOnFaulted ) ;
554
+ results ??= _emptyResult ;
555
+
556
+ if ( ! _resultsUpdateChannelWriter . TryWrite ( new ResultsForUpdate ( results , plugin . Metadata , query , currentCancellationToken ) ) )
557
+ {
558
+ Log . Error ( "MainViewModel" , "Unable to add item to Result Update Queue" ) ;
559
+ }
560
+ }
549
561
}
550
562
551
563
0 commit comments