@@ -17,6 +17,8 @@ public class ResultsViewModel : BaseModel
1717 {
1818 #region Private Fields
1919
20+ private readonly string ClassName = nameof ( ResultsViewModel ) ;
21+
2022 public ResultCollection Results { get ; }
2123
2224 private readonly object _collectionLock = new ( ) ;
@@ -187,11 +189,9 @@ public void AddResults(List<Result> newRawResults, string resultId)
187189 /// </summary>
188190 public void AddResults ( ICollection < ResultsForUpdate > resultsForUpdates , CancellationToken token , bool reselect = true )
189191 {
192+ // Since NewResults may need to clear existing results, do not check token cancellation after this point
190193 var newResults = NewResults ( resultsForUpdates ) ;
191194
192- if ( token . IsCancellationRequested )
193- return ;
194-
195195 UpdateResults ( newResults , reselect , token ) ;
196196 }
197197
@@ -240,16 +240,20 @@ private List<ResultViewModel> NewResults(List<Result> newRawResults, string resu
240240 private List < ResultViewModel > NewResults ( ICollection < ResultsForUpdate > resultsForUpdates )
241241 {
242242 if ( ! resultsForUpdates . Any ( ) )
243+ {
244+ App . API . LogDebug ( ClassName , "No results for updates, returning existing results" ) ;
243245 return Results ;
246+ }
244247
245248 var newResults = resultsForUpdates . SelectMany ( u => u . Results , ( u , r ) => new ResultViewModel ( r , _settings ) ) ;
246249
247- if ( resultsForUpdates . Any ( x => x . shouldClearExistingResults ) )
250+ if ( resultsForUpdates . Any ( x => x . ShouldClearExistingResults ) )
248251 {
249- App . API . LogDebug ( "NewResults" , $ "Existing results are cleared for query") ;
252+ App . API . LogDebug ( ClassName , $ "Existing results are cleared for query") ;
250253 return newResults . OrderByDescending ( rv => rv . Result . Score ) . ToList ( ) ;
251254 }
252255
256+ App . API . LogDebug ( ClassName , $ "Keeping existing results for { resultsForUpdates . Count } queries") ;
253257 return Results . Where ( r => r ? . Result != null && resultsForUpdates . All ( u => u . ID != r . Result . PluginID ) )
254258 . Concat ( newResults )
255259 . OrderByDescending ( rv => rv . Result . Score )
@@ -293,34 +297,32 @@ public class ResultCollection : List<ResultViewModel>, INotifyCollectionChanged
293297 {
294298 private long editTime = 0 ;
295299
296- private CancellationToken _token ;
297-
298300 public event NotifyCollectionChangedEventHandler CollectionChanged ;
299301
300302 protected void OnCollectionChanged ( NotifyCollectionChangedEventArgs e )
301303 {
302304 CollectionChanged ? . Invoke ( this , e ) ;
303305 }
304306
305- public void BulkAddAll ( List < ResultViewModel > resultViews )
307+ private void BulkAddAll ( List < ResultViewModel > resultViews , CancellationToken token = default )
306308 {
307309 AddRange ( resultViews ) ;
308310
309311 // can return because the list will be cleared next time updated, which include a reset event
310- if ( _token . IsCancellationRequested )
312+ if ( token . IsCancellationRequested )
311313 return ;
312314
313315 // manually update event
314316 // wpf use DirectX / double buffered already, so just reset all won't cause ui flickering
315317 OnCollectionChanged ( new NotifyCollectionChangedEventArgs ( NotifyCollectionChangedAction . Reset ) ) ;
316318 }
317319
318- private void AddAll ( List < ResultViewModel > Items )
320+ private void AddAll ( List < ResultViewModel > Items , CancellationToken token = default )
319321 {
320322 for ( int i = 0 ; i < Items . Count ; i ++ )
321323 {
322324 var item = Items [ i ] ;
323- if ( _token . IsCancellationRequested )
325+ if ( token . IsCancellationRequested )
324326 return ;
325327 Add ( item ) ;
326328 OnCollectionChanged ( new NotifyCollectionChangedEventArgs ( NotifyCollectionChangedAction . Add , item , i ) ) ;
@@ -342,21 +344,30 @@ public void RemoveAll(int Capacity = 512)
342344 /// <param name="newItems"></param>
343345 public void Update ( List < ResultViewModel > newItems , CancellationToken token = default )
344346 {
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 )
347349 return ;
348350
349351 if ( editTime < 10 || newItems . Count < 30 )
350352 {
351353 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 ) ;
353360 editTime ++ ;
354- return ;
355361 }
356362 else
357363 {
358364 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 ) ;
360371 if ( Capacity > 8000 && newItems . Count < 3000 )
361372 {
362373 Capacity = newItems . Count ;
0 commit comments