@@ -46,6 +46,7 @@ public partial class MainViewModel : BaseModel, ISavable, IDisposable
4646 private readonly TopMostRecord _topMostRecord ;
4747
4848 private CancellationTokenSource _updateSource ; // Used to cancel old query flows
49+ private CancellationToken _updateToken ; // Used to avoid ObjectDisposedException of _updateSource.Token
4950
5051 private ChannelWriter < ResultsForUpdate > _resultsUpdateChannelWriter ;
5152 private Task _resultsViewUpdateTask ;
@@ -68,6 +69,8 @@ public MainViewModel()
6869 _queryText = "" ;
6970 _lastQuery = new Query ( ) ;
7071 _ignoredQueryText = null ; // null as invalid value
72+ _updateSource = new CancellationTokenSource ( ) ;
73+ _updateToken = _updateSource . Token ;
7174
7275 Settings = Ioc . Default . GetRequiredService < Settings > ( ) ;
7376 Settings . PropertyChanged += ( _ , args ) =>
@@ -249,7 +252,7 @@ public void RegisterResultsUpdatedEvent()
249252 return ;
250253 }
251254
252- var token = e . Token == default ? _updateSource . Token : e . Token ;
255+ var token = e . Token == default ? _updateToken : e . Token ;
253256
254257 // make a clone to avoid possible issue that plugin will also change the list and items when updating view model
255258 var resultsCopy = DeepCloneResults ( e . Results , token ) ;
@@ -1265,15 +1268,17 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
12651268
12661269 var isHomeQuery = query . RawQuery == string . Empty ;
12671270
1271+ _updateSource ? . Dispose ( ) ; // Dispose old update source to fix possible cancellation issue
12681272 _updateSource = new CancellationTokenSource ( ) ;
1273+ _updateToken = _updateSource . Token ;
12691274
12701275 ProgressBarVisibility = Visibility . Hidden ;
12711276 _isQueryRunning = true ;
12721277
12731278 // Switch to ThreadPool thread
12741279 await TaskScheduler . Default ;
12751280
1276- if ( _updateSource . Token . IsCancellationRequested ) return ;
1281+ if ( _updateToken . IsCancellationRequested ) return ;
12771282
12781283 // Update the query's IsReQuery property to true if this is a re-query
12791284 query . IsReQuery = isReQuery ;
@@ -1322,20 +1327,19 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
13221327 {
13231328 // Wait 15 millisecond for query change in global query
13241329 // if query changes, return so that it won't be calculated
1325- await Task.Delay(15, _updateSource.Token);
1326- if (_updateSource.Token.IsCancellationRequested)
1327- return;
1330+ await Task.Delay(15, _updateToken);
1331+ if (_updateToken.IsCancellationRequested) return;
13281332 }*/
13291333
1330- _ = Task . Delay ( 200 , _updateSource . Token ) . ContinueWith ( _ =>
1334+ _ = Task . Delay ( 200 , _updateToken ) . ContinueWith ( _ =>
13311335 {
13321336 // start the progress bar if query takes more than 200 ms and this is the current running query and it didn't finish yet
13331337 if ( _isQueryRunning )
13341338 {
13351339 ProgressBarVisibility = Visibility . Visible ;
13361340 }
13371341 } ,
1338- _updateSource . Token ,
1342+ _updateToken ,
13391343 TaskContinuationOptions . NotOnCanceled ,
13401344 TaskScheduler . Default ) ;
13411345
@@ -1346,7 +1350,7 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
13461350 {
13471351 tasks = plugins . Select ( plugin => plugin . Metadata . HomeDisabled switch
13481352 {
1349- false => QueryTaskAsync ( plugin , _updateSource . Token ) ,
1353+ false => QueryTaskAsync ( plugin , _updateToken ) ,
13501354 true => Task . CompletedTask
13511355 } ) . ToArray ( ) ;
13521356
@@ -1360,7 +1364,7 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
13601364 {
13611365 tasks = plugins . Select ( plugin => plugin . Metadata . Disabled switch
13621366 {
1363- false => QueryTaskAsync ( plugin , _updateSource . Token ) ,
1367+ false => QueryTaskAsync ( plugin , _updateToken ) ,
13641368 true => Task . CompletedTask
13651369 } ) . ToArray ( ) ;
13661370 }
@@ -1375,13 +1379,13 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
13751379 // nothing to do here
13761380 }
13771381
1378- if ( _updateSource . Token . IsCancellationRequested ) return ;
1382+ if ( _updateToken . IsCancellationRequested ) return ;
13791383
13801384 // this should happen once after all queries are done so progress bar should continue
13811385 // until the end of all querying
13821386 _isQueryRunning = false ;
13831387
1384- if ( ! _updateSource . Token . IsCancellationRequested )
1388+ if ( ! _updateToken . IsCancellationRequested )
13851389 {
13861390 // update to hidden if this is still the current query
13871391 ProgressBarVisibility = Visibility . Hidden ;
@@ -1448,12 +1452,12 @@ void QueryHistoryTask()
14481452
14491453 var results = GetHistoryItems ( historyItems ) ;
14501454
1451- if ( _updateSource . Token . IsCancellationRequested ) return ;
1455+ if ( _updateToken . IsCancellationRequested ) return ;
14521456
14531457 App . API . LogDebug ( ClassName , $ "Update results for history") ;
14541458
14551459 if ( ! _resultsUpdateChannelWriter . TryWrite ( new ResultsForUpdate ( results , _historyMetadata , query ,
1456- _updateSource . Token ) ) )
1460+ _updateToken ) ) )
14571461 {
14581462 App . API . LogError ( ClassName , "Unable to add item to Result Update Queue" ) ;
14591463 }
0 commit comments