@@ -17,6 +17,8 @@ public class ResultsViewModel : BaseModel
17
17
{
18
18
#region Private Fields
19
19
20
+ private readonly string ClassName = nameof ( ResultsViewModel ) ;
21
+
20
22
public ResultCollection Results { get ; }
21
23
22
24
private readonly object _collectionLock = new ( ) ;
@@ -187,11 +189,9 @@ public void AddResults(List<Result> newRawResults, string resultId)
187
189
/// </summary>
188
190
public void AddResults ( ICollection < ResultsForUpdate > resultsForUpdates , CancellationToken token , bool reselect = true )
189
191
{
192
+ // Since NewResults may need to clear existing results, do not check token cancellation after this point
190
193
var newResults = NewResults ( resultsForUpdates ) ;
191
194
192
- if ( token . IsCancellationRequested )
193
- return ;
194
-
195
195
UpdateResults ( newResults , reselect , token ) ;
196
196
}
197
197
@@ -240,16 +240,20 @@ private List<ResultViewModel> NewResults(List<Result> newRawResults, string resu
240
240
private List < ResultViewModel > NewResults ( ICollection < ResultsForUpdate > resultsForUpdates )
241
241
{
242
242
if ( ! resultsForUpdates . Any ( ) )
243
+ {
244
+ App . API . LogDebug ( ClassName , "No results for updates, returning existing results" ) ;
243
245
return Results ;
246
+ }
244
247
245
248
var newResults = resultsForUpdates . SelectMany ( u => u . Results , ( u , r ) => new ResultViewModel ( r , _settings ) ) ;
246
249
247
- if ( resultsForUpdates . Any ( x => x . shouldClearExistingResults ) )
250
+ if ( resultsForUpdates . Any ( x => x . ShouldClearExistingResults ) )
248
251
{
249
- App . API . LogDebug ( "NewResults" , $ "Existing results are cleared for query") ;
252
+ App . API . LogDebug ( ClassName , $ "Existing results are cleared for query") ;
250
253
return newResults . OrderByDescending ( rv => rv . Result . Score ) . ToList ( ) ;
251
254
}
252
255
256
+ App . API . LogDebug ( ClassName , $ "Keeping existing results for { resultsForUpdates . Count } queries") ;
253
257
return Results . Where ( r => r ? . Result != null && resultsForUpdates . All ( u => u . ID != r . Result . PluginID ) )
254
258
. Concat ( newResults )
255
259
. OrderByDescending ( rv => rv . Result . Score )
@@ -293,34 +297,32 @@ public class ResultCollection : List<ResultViewModel>, INotifyCollectionChanged
293
297
{
294
298
private long editTime = 0 ;
295
299
296
- private CancellationToken _token ;
297
-
298
300
public event NotifyCollectionChangedEventHandler CollectionChanged ;
299
301
300
302
protected void OnCollectionChanged ( NotifyCollectionChangedEventArgs e )
301
303
{
302
304
CollectionChanged ? . Invoke ( this , e ) ;
303
305
}
304
306
305
- public void BulkAddAll ( List < ResultViewModel > resultViews )
307
+ private void BulkAddAll ( List < ResultViewModel > resultViews , CancellationToken token = default )
306
308
{
307
309
AddRange ( resultViews ) ;
308
310
309
311
// can return because the list will be cleared next time updated, which include a reset event
310
- if ( _token . IsCancellationRequested )
312
+ if ( token . IsCancellationRequested )
311
313
return ;
312
314
313
315
// manually update event
314
316
// wpf use DirectX / double buffered already, so just reset all won't cause ui flickering
315
317
OnCollectionChanged ( new NotifyCollectionChangedEventArgs ( NotifyCollectionChangedAction . Reset ) ) ;
316
318
}
317
319
318
- private void AddAll ( List < ResultViewModel > Items )
320
+ private void AddAll ( List < ResultViewModel > Items , CancellationToken token = default )
319
321
{
320
322
for ( int i = 0 ; i < Items . Count ; i ++ )
321
323
{
322
324
var item = Items [ i ] ;
323
- if ( _token . IsCancellationRequested )
325
+ if ( token . IsCancellationRequested )
324
326
return ;
325
327
Add ( item ) ;
326
328
OnCollectionChanged ( new NotifyCollectionChangedEventArgs ( NotifyCollectionChangedAction . Add , item , i ) ) ;
@@ -342,21 +344,30 @@ public void RemoveAll(int Capacity = 512)
342
344
/// <param name="newItems"></param>
343
345
public void Update ( List < ResultViewModel > newItems , CancellationToken token = default )
344
346
{
345
- _token = token ;
346
- if ( Count == 0 && newItems . Count == 0 || _token . IsCancellationRequested )
347
+ // Since NewResults may need to clear existing results, so we cannot check token cancellation here
348
+ if ( Count == 0 && newItems . Count == 0 )
347
349
return ;
348
350
349
351
if ( editTime < 10 || newItems . Count < 30 )
350
352
{
351
353
if ( Count != 0 ) RemoveAll ( newItems . Count ) ;
352
- AddAll ( newItems ) ;
354
+
355
+ // After results are removed, we need to check the token cancellation
356
+ // so that we will not add new items from the cancelled queries
357
+ if ( token . IsCancellationRequested ) return ;
358
+
359
+ AddAll ( newItems , token ) ;
353
360
editTime ++ ;
354
- return ;
355
361
}
356
362
else
357
363
{
358
364
Clear ( ) ;
359
- BulkAddAll ( newItems ) ;
365
+
366
+ // After results are removed, we need to check the token cancellation
367
+ // so that we will not add new items from the cancelled queries
368
+ if ( token . IsCancellationRequested ) return ;
369
+
370
+ BulkAddAll ( newItems , token ) ;
360
371
if ( Capacity > 8000 && newItems . Count < 3000 )
361
372
{
362
373
Capacity = newItems . Count ;
0 commit comments