@@ -46,6 +46,7 @@ public partial class MainViewModel : BaseModel, ISavable, IDisposable
46
46
private readonly TopMostRecord _topMostRecord ;
47
47
48
48
private CancellationTokenSource _updateSource ; // Used to cancel old query flows
49
+ private CancellationToken _updateToken ; // Used to avoid ObjectDisposedException of _updateSource.Token
49
50
50
51
private ChannelWriter < ResultsForUpdate > _resultsUpdateChannelWriter ;
51
52
private Task _resultsViewUpdateTask ;
@@ -68,6 +69,8 @@ public MainViewModel()
68
69
_queryText = "" ;
69
70
_lastQuery = new Query ( ) ;
70
71
_ignoredQueryText = null ; // null as invalid value
72
+ _updateSource = new CancellationTokenSource ( ) ;
73
+ _updateToken = _updateSource . Token ;
71
74
72
75
Settings = Ioc . Default . GetRequiredService < Settings > ( ) ;
73
76
Settings . PropertyChanged += ( _ , args ) =>
@@ -249,7 +252,7 @@ public void RegisterResultsUpdatedEvent()
249
252
return ;
250
253
}
251
254
252
- var token = e . Token == default ? _updateSource . Token : e . Token ;
255
+ var token = e . Token == default ? _updateToken : e . Token ;
253
256
254
257
// make a clone to avoid possible issue that plugin will also change the list and items when updating view model
255
258
var resultsCopy = DeepCloneResults ( e . Results , token ) ;
@@ -1265,15 +1268,17 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
1265
1268
1266
1269
var isHomeQuery = query . RawQuery == string . Empty ;
1267
1270
1271
+ _updateSource ? . Dispose ( ) ; // Dispose old update source to fix possible cancellation issue
1268
1272
_updateSource = new CancellationTokenSource ( ) ;
1273
+ _updateToken = _updateSource . Token ;
1269
1274
1270
1275
ProgressBarVisibility = Visibility . Hidden ;
1271
1276
_isQueryRunning = true ;
1272
1277
1273
1278
// Switch to ThreadPool thread
1274
1279
await TaskScheduler . Default ;
1275
1280
1276
- if ( _updateSource . Token . IsCancellationRequested ) return ;
1281
+ if ( _updateToken . IsCancellationRequested ) return ;
1277
1282
1278
1283
// Update the query's IsReQuery property to true if this is a re-query
1279
1284
query . IsReQuery = isReQuery ;
@@ -1322,20 +1327,19 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
1322
1327
{
1323
1328
// Wait 15 millisecond for query change in global query
1324
1329
// 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;
1328
1332
}*/
1329
1333
1330
- _ = Task . Delay ( 200 , _updateSource . Token ) . ContinueWith ( _ =>
1334
+ _ = Task . Delay ( 200 , _updateToken ) . ContinueWith ( _ =>
1331
1335
{
1332
1336
// start the progress bar if query takes more than 200 ms and this is the current running query and it didn't finish yet
1333
1337
if ( _isQueryRunning )
1334
1338
{
1335
1339
ProgressBarVisibility = Visibility . Visible ;
1336
1340
}
1337
1341
} ,
1338
- _updateSource . Token ,
1342
+ _updateToken ,
1339
1343
TaskContinuationOptions . NotOnCanceled ,
1340
1344
TaskScheduler . Default ) ;
1341
1345
@@ -1346,7 +1350,7 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
1346
1350
{
1347
1351
tasks = plugins . Select ( plugin => plugin . Metadata . HomeDisabled switch
1348
1352
{
1349
- false => QueryTaskAsync ( plugin , _updateSource . Token ) ,
1353
+ false => QueryTaskAsync ( plugin , _updateToken ) ,
1350
1354
true => Task . CompletedTask
1351
1355
} ) . ToArray ( ) ;
1352
1356
@@ -1360,7 +1364,7 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
1360
1364
{
1361
1365
tasks = plugins . Select ( plugin => plugin . Metadata . Disabled switch
1362
1366
{
1363
- false => QueryTaskAsync ( plugin , _updateSource . Token ) ,
1367
+ false => QueryTaskAsync ( plugin , _updateToken ) ,
1364
1368
true => Task . CompletedTask
1365
1369
} ) . ToArray ( ) ;
1366
1370
}
@@ -1375,13 +1379,13 @@ private async Task QueryResultsAsync(bool searchDelay, bool isReQuery = false, b
1375
1379
// nothing to do here
1376
1380
}
1377
1381
1378
- if ( _updateSource . Token . IsCancellationRequested ) return ;
1382
+ if ( _updateToken . IsCancellationRequested ) return ;
1379
1383
1380
1384
// this should happen once after all queries are done so progress bar should continue
1381
1385
// until the end of all querying
1382
1386
_isQueryRunning = false ;
1383
1387
1384
- if ( ! _updateSource . Token . IsCancellationRequested )
1388
+ if ( ! _updateToken . IsCancellationRequested )
1385
1389
{
1386
1390
// update to hidden if this is still the current query
1387
1391
ProgressBarVisibility = Visibility . Hidden ;
@@ -1448,12 +1452,12 @@ void QueryHistoryTask()
1448
1452
1449
1453
var results = GetHistoryItems ( historyItems ) ;
1450
1454
1451
- if ( _updateSource . Token . IsCancellationRequested ) return ;
1455
+ if ( _updateToken . IsCancellationRequested ) return ;
1452
1456
1453
1457
App . API . LogDebug ( ClassName , $ "Update results for history") ;
1454
1458
1455
1459
if ( ! _resultsUpdateChannelWriter . TryWrite ( new ResultsForUpdate ( results , _historyMetadata , query ,
1456
- _updateSource . Token ) ) )
1460
+ _updateToken ) ) )
1457
1461
{
1458
1462
App . API . LogError ( ClassName , "Unable to add item to Result Update Queue" ) ;
1459
1463
}
0 commit comments