File tree Expand file tree Collapse file tree 2 files changed +36
-10
lines changed
src/PowerShellEditorServices/Utility
test/PowerShellEditorServices.Test/Utility Expand file tree Collapse file tree 2 files changed +36
-10
lines changed Original file line number Diff line number Diff line change @@ -73,18 +73,24 @@ public async Task EnqueueAsync(T item)
73
73
{
74
74
using ( await queueLock . LockAsync ( ) )
75
75
{
76
- if ( this . requestQueue . Count > 0 )
77
- {
78
- // There are requests waiting, immediately dispatch the item
79
- TaskCompletionSource < T > requestTaskSource = this . requestQueue . Dequeue ( ) ;
80
- requestTaskSource . SetResult ( item ) ;
81
- }
82
- else
76
+ TaskCompletionSource < T > requestTaskSource = null ;
77
+
78
+ // Are any requests waiting?
79
+ while ( this . requestQueue . Count > 0 )
83
80
{
84
- // No requests waiting, queue the item for a later request
85
- this . itemQueue . Enqueue ( item ) ;
86
- this . IsEmpty = false ;
81
+ // Is the next request cancelled already?
82
+ requestTaskSource = this . requestQueue . Dequeue ( ) ;
83
+ if ( ! requestTaskSource . Task . IsCanceled )
84
+ {
85
+ // Dispatch the item
86
+ requestTaskSource . SetResult ( item ) ;
87
+ return ;
88
+ }
87
89
}
90
+
91
+ // No more requests waiting, queue the item for a later request
92
+ this . itemQueue . Enqueue ( item ) ;
93
+ this . IsEmpty = false ;
88
94
}
89
95
}
90
96
Original file line number Diff line number Diff line change @@ -56,6 +56,26 @@ await Task.WhenAll(
56
56
Assert . Equal ( 0 , expectedItems . Except ( outputItems ) . Count ( ) ) ;
57
57
}
58
58
59
+ [ Fact ]
60
+ public async Task AsyncQueueSkipsCancelledTasks ( )
61
+ {
62
+ AsyncQueue < int > inputQueue = new AsyncQueue < int > ( ) ;
63
+
64
+ // Queue up a couple of tasks to wait for input
65
+ CancellationTokenSource cancellationSource = new CancellationTokenSource ( ) ;
66
+ Task < int > taskOne = inputQueue . DequeueAsync ( cancellationSource . Token ) ;
67
+ Task < int > taskTwo = inputQueue . DequeueAsync ( ) ;
68
+
69
+ // Cancel the first task and then enqueue a number
70
+ cancellationSource . Cancel ( ) ;
71
+ await inputQueue . EnqueueAsync ( 1 ) ;
72
+
73
+ // Did the second task get the number?
74
+ Assert . Equal ( TaskStatus . Canceled , taskOne . Status ) ;
75
+ Assert . Equal ( TaskStatus . RanToCompletion , taskTwo . Status ) ;
76
+ Assert . Equal ( 1 , taskTwo . Result ) ;
77
+ }
78
+
59
79
private async Task ConsumeItems (
60
80
AsyncQueue < int > inputQueue ,
61
81
ConcurrentBag < int > outputItems ,
You can’t perform that action at this time.
0 commit comments