@@ -49,16 +49,10 @@ public SemanticChangeProcessor(
4949
5050 Start ( ) ;
5151
52+ // Register a clean-up task to ensure pending work items are flushed from the queue if they will
53+ // never be processed.
5254 AsyncProcessorTask . ContinueWith (
53- _ =>
54- {
55- foreach ( var ( documentId , data ) in _pendingWork )
56- {
57- data . AsyncToken . Dispose ( ) ;
58- }
59-
60- _pendingWork . Clear ( ) ;
61- } ,
55+ _ => ClearQueueWorker ( _workGate , _pendingWork , data => data . AsyncToken ) ,
6256 CancellationToken . None ,
6357 TaskContinuationOptions . ExecuteSynchronously ,
6458 TaskScheduler . Default ) ;
@@ -296,6 +290,19 @@ private static TValue DequeueWorker<TKey, TValue>(NonReentrantLock gate, Diction
296290 }
297291 }
298292
293+ private static void ClearQueueWorker < TKey , TValue > ( NonReentrantLock gate , Dictionary < TKey , TValue > map , Func < TValue , IDisposable > disposerSelector )
294+ {
295+ using ( gate . DisposableWait ( CancellationToken . None ) )
296+ {
297+ foreach ( var ( _, data ) in map )
298+ {
299+ disposerSelector ? . Invoke ( data ) ? . Dispose ( ) ;
300+ }
301+
302+ map . Clear ( ) ;
303+ }
304+ }
305+
299306 private static IEnumerable < ProjectId > GetProjectsToAnalyze ( Solution solution , ProjectId projectId )
300307 {
301308 var graph = solution . GetProjectDependencyGraph ( ) ;
@@ -354,16 +361,10 @@ public ProjectProcessor(
354361
355362 Start ( ) ;
356363
364+ // Register a clean-up task to ensure pending work items are flushed from the queue if they will
365+ // never be processed.
357366 AsyncProcessorTask . ContinueWith (
358- _ =>
359- {
360- foreach ( var ( projectId , data ) in _pendingWork )
361- {
362- data . AsyncToken . Dispose ( ) ;
363- }
364-
365- _pendingWork . Clear ( ) ;
366- } ,
367+ _ => ClearQueueWorker ( _workGate , _pendingWork , data => data . AsyncToken ) ,
367368 CancellationToken . None ,
368369 TaskContinuationOptions . ExecuteSynchronously ,
369370 TaskScheduler . Default ) ;
0 commit comments