@@ -235,7 +235,7 @@ public async Task StartAsync(CancellationToken cancellationToken = default)
235
235
236
236
private async Task StartAsyncInner ( CancellationToken cancellationToken = default )
237
237
{
238
- await _state . WaitConnectionLockAsync ( ) ;
238
+ await _state . WaitConnectionLockAsync ( token : cancellationToken ) ;
239
239
try
240
240
{
241
241
if ( ! _state . TryChangeState ( HubConnectionState . Disconnected , HubConnectionState . Connecting ) )
@@ -465,7 +465,7 @@ private async Task StopAsyncCore(bool disposing)
465
465
466
466
// Potentially wait for StartAsync to finish, and block a new StartAsync from
467
467
// starting until we've finished stopping.
468
- await _state . WaitConnectionLockAsync ( ) ;
468
+ await _state . WaitConnectionLockAsync ( token : default ) ;
469
469
470
470
// Ensure that ReconnectingState.ReconnectTask is not accessed outside of the lock.
471
471
var reconnectTask = _state . ReconnectTask ;
@@ -478,7 +478,7 @@ private async Task StopAsyncCore(bool disposing)
478
478
// The StopCts should prevent the HubConnection from restarting until it is reset.
479
479
_state . ReleaseConnectionLock ( ) ;
480
480
await reconnectTask ;
481
- await _state . WaitConnectionLockAsync ( ) ;
481
+ await _state . WaitConnectionLockAsync ( token : default ) ;
482
482
}
483
483
484
484
ConnectionState connectionState ;
@@ -574,7 +574,7 @@ private async Task<ChannelReader<object>> StreamAsChannelCoreAsyncCore(string me
574
574
async Task OnStreamCanceled ( InvocationRequest irq )
575
575
{
576
576
// We need to take the connection lock in order to ensure we a) have a connection and b) are the only one accessing the write end of the pipe.
577
- await _state . WaitConnectionLockAsync ( ) ;
577
+ await _state . WaitConnectionLockAsync ( token : default ) ;
578
578
try
579
579
{
580
580
if ( _state . CurrentConnectionStateUnsynchronized != null )
@@ -601,7 +601,7 @@ async Task OnStreamCanceled(InvocationRequest irq)
601
601
var readers = default ( Dictionary < string , object > ) ;
602
602
603
603
CheckDisposed ( ) ;
604
- var connectionState = await _state . WaitForActiveConnectionAsync ( nameof ( StreamAsChannelCoreAsync ) ) ;
604
+ var connectionState = await _state . WaitForActiveConnectionAsync ( nameof ( StreamAsChannelCoreAsync ) , token : cancellationToken ) ;
605
605
606
606
ChannelReader < object > channel ;
607
607
try
@@ -704,7 +704,7 @@ async Task ReadChannelStream(CancellationTokenSource tokenSource)
704
704
{
705
705
while ( ! tokenSource . Token . IsCancellationRequested && reader . TryRead ( out var item ) )
706
706
{
707
- await SendWithLock ( connectionState , new StreamItemMessage ( streamId , item ) ) ;
707
+ await SendWithLock ( connectionState , new StreamItemMessage ( streamId , item ) , tokenSource . Token ) ;
708
708
Log . SendingStreamItem ( _logger , streamId ) ;
709
709
}
710
710
}
@@ -722,7 +722,7 @@ async Task ReadAsyncEnumerableStream(CancellationTokenSource tokenSource)
722
722
723
723
await foreach ( var streamValue in streamValues )
724
724
{
725
- await SendWithLock ( connectionState , new StreamItemMessage ( streamId , streamValue ) ) ;
725
+ await SendWithLock ( connectionState , new StreamItemMessage ( streamId , streamValue ) , tokenSource . Token ) ;
726
726
Log . SendingStreamItem ( _logger , streamId ) ;
727
727
}
728
728
}
@@ -750,15 +750,17 @@ private async Task CommonStreaming(ConnectionState connectionState, string strea
750
750
751
751
Log . CompletingStream ( _logger , streamId ) ;
752
752
753
- await SendWithLock ( connectionState , CompletionMessage . WithError ( streamId , responseError ) , cts . Token ) ;
753
+ // Don't use cancellation token here
754
+ // this is triggered by a cancellation token to tell the server that the client is done streaming
755
+ await SendWithLock ( connectionState , CompletionMessage . WithError ( streamId , responseError ) , cancellationToken : default ) ;
754
756
}
755
757
756
758
private async Task < object > InvokeCoreAsyncCore ( string methodName , Type returnType , object [ ] args , CancellationToken cancellationToken )
757
759
{
758
760
var readers = default ( Dictionary < string , object > ) ;
759
761
760
762
CheckDisposed ( ) ;
761
- var connectionState = await _state . WaitForActiveConnectionAsync ( nameof ( InvokeCoreAsync ) ) ;
763
+ var connectionState = await _state . WaitForActiveConnectionAsync ( nameof ( InvokeCoreAsync ) , token : cancellationToken ) ;
762
764
763
765
Task < object > invocationTask ;
764
766
try
@@ -853,7 +855,7 @@ private async Task SendCoreAsyncCore(string methodName, object[] args, Cancellat
853
855
var readers = default ( Dictionary < string , object > ) ;
854
856
855
857
CheckDisposed ( ) ;
856
- var connectionState = await _state . WaitForActiveConnectionAsync ( nameof ( SendCoreAsync ) ) ;
858
+ var connectionState = await _state . WaitForActiveConnectionAsync ( nameof ( SendCoreAsync ) , token : cancellationToken ) ;
857
859
try
858
860
{
859
861
CheckDisposed ( ) ;
@@ -872,10 +874,10 @@ private async Task SendCoreAsyncCore(string methodName, object[] args, Cancellat
872
874
}
873
875
}
874
876
875
- private async Task SendWithLock ( ConnectionState expectedConnectionState , HubMessage message , CancellationToken cancellationToken = default , [ CallerMemberName ] string callerName = "" )
877
+ private async Task SendWithLock ( ConnectionState expectedConnectionState , HubMessage message , CancellationToken cancellationToken , [ CallerMemberName ] string callerName = "" )
876
878
{
877
879
CheckDisposed ( ) ;
878
- var connectionState = await _state . WaitForActiveConnectionAsync ( callerName ) ;
880
+ var connectionState = await _state . WaitForActiveConnectionAsync ( callerName , token : cancellationToken ) ;
879
881
try
880
882
{
881
883
CheckDisposed ( ) ;
@@ -1245,7 +1247,7 @@ internal void OnServerTimeout()
1245
1247
private async Task HandleConnectionClose ( ConnectionState connectionState )
1246
1248
{
1247
1249
// Clear the connectionState field
1248
- await _state . WaitConnectionLockAsync ( ) ;
1250
+ await _state . WaitConnectionLockAsync ( token : default ) ;
1249
1251
try
1250
1252
{
1251
1253
SafeAssert ( ReferenceEquals ( _state . CurrentConnectionStateUnsynchronized , connectionState ) ,
@@ -1363,7 +1365,7 @@ private async Task ReconnectAsync(Exception closeException)
1363
1365
{
1364
1366
Log . ReconnectingStoppedDuringRetryDelay ( _logger ) ;
1365
1367
1366
- await _state . WaitConnectionLockAsync ( ) ;
1368
+ await _state . WaitConnectionLockAsync ( token : default ) ;
1367
1369
try
1368
1370
{
1369
1371
_state . ChangeState ( HubConnectionState . Reconnecting , HubConnectionState . Disconnected ) ;
@@ -1378,7 +1380,7 @@ private async Task ReconnectAsync(Exception closeException)
1378
1380
return ;
1379
1381
}
1380
1382
1381
- await _state . WaitConnectionLockAsync ( ) ;
1383
+ await _state . WaitConnectionLockAsync ( token : default ) ;
1382
1384
try
1383
1385
{
1384
1386
SafeAssert ( ReferenceEquals ( _state . CurrentConnectionStateUnsynchronized , null ) ,
@@ -1417,7 +1419,7 @@ private async Task ReconnectAsync(Exception closeException)
1417
1419
nextRetryDelay = GetNextRetryDelay ( previousReconnectAttempts ++ , DateTime . UtcNow - reconnectStartTime , retryReason ) ;
1418
1420
}
1419
1421
1420
- await _state . WaitConnectionLockAsync ( ) ;
1422
+ await _state . WaitConnectionLockAsync ( token : default ) ;
1421
1423
try
1422
1424
{
1423
1425
SafeAssert ( ReferenceEquals ( _state . CurrentConnectionStateUnsynchronized , null ) ,
@@ -1956,10 +1958,10 @@ public void AssertConnectionValid([CallerMemberName] string memberName = null, [
1956
1958
SafeAssert ( CurrentConnectionStateUnsynchronized != null , "We don't have a connection!" , memberName , fileName , lineNumber ) ;
1957
1959
}
1958
1960
1959
- public Task WaitConnectionLockAsync ( [ CallerMemberName ] string memberName = null , [ CallerFilePath ] string filePath = null , [ CallerLineNumber ] int lineNumber = 0 )
1961
+ public Task WaitConnectionLockAsync ( CancellationToken token , [ CallerMemberName ] string memberName = null , [ CallerFilePath ] string filePath = null , [ CallerLineNumber ] int lineNumber = 0 )
1960
1962
{
1961
1963
Log . WaitingOnConnectionLock ( _logger , memberName , filePath , lineNumber ) ;
1962
- return _connectionLock . WaitAsync ( ) ;
1964
+ return _connectionLock . WaitAsync ( token ) ;
1963
1965
}
1964
1966
1965
1967
public bool TryAcquireConnectionLock ( )
@@ -1968,9 +1970,9 @@ public bool TryAcquireConnectionLock()
1968
1970
}
1969
1971
1970
1972
// Don't call this method in a try/finally that releases the lock since we're also potentially releasing the connection lock here.
1971
- public async Task < ConnectionState > WaitForActiveConnectionAsync ( string methodName , [ CallerMemberName ] string memberName = null , [ CallerFilePath ] string filePath = null , [ CallerLineNumber ] int lineNumber = 0 )
1973
+ public async Task < ConnectionState > WaitForActiveConnectionAsync ( string methodName , CancellationToken token , [ CallerMemberName ] string memberName = null , [ CallerFilePath ] string filePath = null , [ CallerLineNumber ] int lineNumber = 0 )
1972
1974
{
1973
- await WaitConnectionLockAsync ( methodName ) ;
1975
+ await WaitConnectionLockAsync ( token , methodName ) ;
1974
1976
1975
1977
if ( CurrentConnectionStateUnsynchronized == null || CurrentConnectionStateUnsynchronized . Stopping )
1976
1978
{
0 commit comments