@@ -18,7 +18,8 @@ public class FiberTaskWaiter : IDisposable
1818 private readonly ManualResetEventSlim _notifierExecutionFinished = new ManualResetEventSlim ( ) ;
1919 private readonly UserThreadPool _thread ;
2020 private bool _inExecuting ;
21- private CancellationToken _cancellationToken ;
21+ private CancellationToken _cancellationTokenExternal ;
22+ private readonly CancellationTokenSource _onDispose = new CancellationTokenSource ( ) ;
2223
2324 /// <summary>
2425 /// Register a task to the sequential task list.
@@ -28,7 +29,7 @@ public class FiberTaskWaiter : IDisposable
2829 public FiberTaskWaiter ( ISequentialTaskListRegistry taskList , CancellationToken cancellationToken = default )
2930 {
3031 _thread = UserThreadPool . StartNew ( 1 ) ;
31- _cancellationToken = cancellationToken ;
32+ _cancellationTokenExternal = cancellationToken ;
3233 _unsubscriber = taskList . Add ( ExecuteAsync ) ;
3334 }
3435
@@ -45,7 +46,7 @@ public async Task ExecuteAsync()
4546 {
4647 return ;
4748 }
48- if ( _cancellationToken . IsCancellationRequested )
49+ if ( _cancellationTokenExternal . IsCancellationRequested )
4950 {
5051 return ;
5152 }
@@ -69,7 +70,8 @@ public async Task ExecuteAsync()
6970
7071 try
7172 {
72- await _thread . RegisterWaitForSingleObjectAsync ( _notifierExecutionFinished . WaitHandle , _cancellationToken ) . ConfigureAwait ( false ) ;
73+ var cancellation = CancellationTokenSource . CreateLinkedTokenSource ( _cancellationTokenExternal , _onDispose . Token ) ;
74+ await _thread . RegisterWaitForSingleObjectAsync ( _notifierExecutionFinished . WaitHandle , cancellation . Token ) . ConfigureAwait ( false ) ;
7375 }
7476 catch ( OperationCanceledException )
7577 {
@@ -95,7 +97,7 @@ public async Task ExecutionStarted()
9597 {
9698 throw new ObjectDisposedException ( GetType ( ) . FullName ) ;
9799 }
98- if ( _cancellationToken . IsCancellationRequested )
100+ if ( _cancellationTokenExternal . IsCancellationRequested )
99101 {
100102 throw new OperationCanceledException ( ) ;
101103 }
@@ -108,7 +110,24 @@ public async Task ExecutionStarted()
108110 }
109111 }
110112
111- await _thread . RegisterWaitForSingleObjectAsync ( _notifierExecutionRequested . WaitHandle , _cancellationToken ) . ConfigureAwait ( false ) ;
113+ using ( var linkedCts = CancellationTokenSource . CreateLinkedTokenSource ( _cancellationTokenExternal , _onDispose . Token ) )
114+ {
115+ try
116+ {
117+ await _thread . RegisterWaitForSingleObjectAsync ( _notifierExecutionRequested . WaitHandle , linkedCts . Token ) . ConfigureAwait ( false ) ;
118+ }
119+ catch ( OperationCanceledException )
120+ {
121+ if ( _cancellationTokenExternal . IsCancellationRequested )
122+ {
123+ _cancellationTokenExternal . ThrowIfCancellationRequested ( ) ;
124+ }
125+ else
126+ {
127+ throw new ObjectDisposedException ( nameof ( FiberTaskWaiter ) ) ;
128+ }
129+ }
130+ }
112131
113132 lock ( _lockObj )
114133 {
@@ -132,6 +151,8 @@ public void Dispose()
132151 _executionRequested = false ;
133152 _inExecuting = false ;
134153 _unsubscriber . Dispose ( ) ;
154+ _onDispose . Cancel ( ) ;
155+ _onDispose . Dispose ( ) ;
135156 _notifierExecutionRequested . Dispose ( ) ;
136157 _notifierExecutionFinished . Dispose ( ) ;
137158 }
0 commit comments