@@ -476,10 +476,8 @@ private void Init(IFrameHandler fh)
476
476
{
477
477
if ( ShouldTriggerConnectionRecovery ( args ) )
478
478
{
479
- if ( ! _recoveryLoopCommandQueue . TryAdd ( RecoveryCommand . BeginAutomaticRecovery ) )
480
- {
481
- ESLog . Warn ( "Failed to notify RecoveryLoop to BeginAutomaticRecovery." ) ;
482
- }
479
+ _recoveryLoopCommandQueue . Enqueue ( RecoveryCommand . BeginAutomaticRecovery ) ;
480
+ _semaphore . Release ( ) ;
483
481
}
484
482
} ;
485
483
lock ( _eventLock )
@@ -963,7 +961,8 @@ private enum RecoveryConnectionState
963
961
private Task _recoveryTask ;
964
962
private RecoveryConnectionState _recoveryLoopState = RecoveryConnectionState . Connected ;
965
963
966
- private readonly BlockingCollection < RecoveryCommand > _recoveryLoopCommandQueue = new BlockingCollection < RecoveryCommand > ( ) ;
964
+ private readonly ConcurrentQueue < RecoveryCommand > _recoveryLoopCommandQueue = new ConcurrentQueue < RecoveryCommand > ( ) ;
965
+ readonly SemaphoreSlim _semaphore = new SemaphoreSlim ( 0 ) ;
967
966
private readonly CancellationTokenSource _recoveryCancellationToken = new CancellationTokenSource ( ) ;
968
967
private readonly TaskCompletionSource < int > _recoveryLoopComplete = new TaskCompletionSource < int > ( ) ;
969
968
@@ -974,19 +973,31 @@ private async Task MainRecoveryLoop()
974
973
{
975
974
try
976
975
{
977
- while ( _recoveryLoopCommandQueue . TryTake ( out RecoveryCommand command , - 1 , _recoveryCancellationToken . Token ) )
976
+ while ( ! _recoveryCancellationToken . IsCancellationRequested )
978
977
{
979
- switch ( _recoveryLoopState )
978
+ try
979
+ {
980
+ await _semaphore . WaitAsync ( _recoveryCancellationToken . Token ) . ConfigureAwait ( false ) ;
981
+ }
982
+ catch ( TaskCanceledException )
980
983
{
981
- case RecoveryConnectionState . Connected :
982
- await RecoveryLoopConnectedHandler ( command ) . ConfigureAwait ( false ) ;
983
- break ;
984
- case RecoveryConnectionState . Recovering :
985
- await RecoveryLoopRecoveringHandler ( command ) . ConfigureAwait ( false ) ;
986
- break ;
987
- default :
988
- ESLog . Warn ( "RecoveryLoop state is out of range." ) ;
989
- break ;
984
+ // Swallowing the task cancellation in case we are stopping work.
985
+ }
986
+
987
+ if ( ! _recoveryCancellationToken . IsCancellationRequested && _recoveryLoopCommandQueue . TryDequeue ( out RecoveryCommand command ) )
988
+ {
989
+ switch ( _recoveryLoopState )
990
+ {
991
+ case RecoveryConnectionState . Connected :
992
+ await RecoveryLoopConnectedHandler ( command ) . ConfigureAwait ( false ) ;
993
+ break ;
994
+ case RecoveryConnectionState . Recovering :
995
+ await RecoveryLoopRecoveringHandler ( command ) . ConfigureAwait ( false ) ;
996
+ break ;
997
+ default :
998
+ ESLog . Warn ( "RecoveryLoop state is out of range." ) ;
999
+ break ;
1000
+ }
990
1001
}
991
1002
}
992
1003
}
@@ -1034,7 +1045,8 @@ private async Task RecoveryLoopRecoveringHandler(RecoveryCommand command)
1034
1045
else
1035
1046
{
1036
1047
await Task . Delay ( _factory . NetworkRecoveryInterval ) ;
1037
- _recoveryLoopCommandQueue . TryAdd ( RecoveryCommand . PerformAutomaticRecovery ) ;
1048
+ _recoveryLoopCommandQueue . Enqueue ( RecoveryCommand . PerformAutomaticRecovery ) ;
1049
+ _semaphore . Release ( ) ;
1038
1050
}
1039
1051
1040
1052
break ;
@@ -1058,7 +1070,8 @@ private async Task RecoveryLoopConnectedHandler(RecoveryCommand command)
1058
1070
case RecoveryCommand . BeginAutomaticRecovery :
1059
1071
_recoveryLoopState = RecoveryConnectionState . Recovering ;
1060
1072
await Task . Delay ( _factory . NetworkRecoveryInterval ) . ConfigureAwait ( false ) ;
1061
- _recoveryLoopCommandQueue . TryAdd ( RecoveryCommand . PerformAutomaticRecovery ) ;
1073
+ _recoveryLoopCommandQueue . Enqueue ( RecoveryCommand . PerformAutomaticRecovery ) ;
1074
+ _semaphore . Release ( ) ;
1062
1075
break ;
1063
1076
default :
1064
1077
ESLog . Warn ( $ "RecoveryLoop command { command } is out of range.") ;
0 commit comments