@@ -287,6 +287,8 @@ private async Task OpenAsync(IOBehavior? ioBehavior, CancellationToken cancellat
287
287
if ( State != ConnectionState . Closed )
288
288
throw new InvalidOperationException ( "Cannot Open when State is {0}." . FormatInvariant ( State ) ) ;
289
289
290
+ var openStartTickCount = Environment . TickCount ;
291
+
290
292
SetState ( ConnectionState . Connecting ) ;
291
293
292
294
var pool = ConnectionPool . GetPool ( m_connectionString ) ;
@@ -309,7 +311,7 @@ private async Task OpenAsync(IOBehavior? ioBehavior, CancellationToken cancellat
309
311
310
312
try
311
313
{
312
- m_session = await CreateSessionAsync ( pool , ioBehavior , cancellationToken ) . ConfigureAwait ( false ) ;
314
+ m_session = await CreateSessionAsync ( pool , openStartTickCount , ioBehavior , cancellationToken ) . ConfigureAwait ( false ) ;
313
315
314
316
m_hasBeenOpened = true ;
315
317
SetState ( ConnectionState . Open ) ;
@@ -621,7 +623,7 @@ internal void FinishQuerying(bool hasWarnings)
621
623
}
622
624
}
623
625
624
- private async ValueTask < ServerSession > CreateSessionAsync ( ConnectionPool ? pool , IOBehavior ? ioBehavior , CancellationToken cancellationToken )
626
+ private async ValueTask < ServerSession > CreateSessionAsync ( ConnectionPool ? pool , int startTickCount , IOBehavior ? ioBehavior , CancellationToken cancellationToken )
625
627
{
626
628
var connectionSettings = GetInitializedConnectionSettings ( ) ;
627
629
var actualIOBehavior = ioBehavior ?? ( connectionSettings . ForceSynchronous ? IOBehavior . Synchronous : IOBehavior . Asynchronous ) ;
@@ -633,7 +635,7 @@ private async ValueTask<ServerSession> CreateSessionAsync(ConnectionPool? pool,
633
635
// the cancellation token for connection is controlled by 'cancellationToken' (if it can be cancelled), ConnectionTimeout
634
636
// (from the connection string, if non-zero), or a combination of both
635
637
if ( connectionSettings . ConnectionTimeout != 0 )
636
- timeoutSource = new CancellationTokenSource ( TimeSpan . FromMilliseconds ( connectionSettings . ConnectionTimeoutMilliseconds ) ) ;
638
+ timeoutSource = new CancellationTokenSource ( TimeSpan . FromMilliseconds ( Math . Max ( 1 , connectionSettings . ConnectionTimeoutMilliseconds - unchecked ( Environment . TickCount - startTickCount ) ) ) ) ;
637
639
if ( cancellationToken . CanBeCanceled && timeoutSource is object )
638
640
linkedSource = CancellationTokenSource . CreateLinkedTokenSource ( cancellationToken , timeoutSource . Token ) ;
639
641
var connectToken = linkedSource ? . Token ?? timeoutSource ? . Token ?? cancellationToken ;
@@ -642,7 +644,7 @@ private async ValueTask<ServerSession> CreateSessionAsync(ConnectionPool? pool,
642
644
if ( pool is object )
643
645
{
644
646
// this returns an open session
645
- return await pool . GetSessionAsync ( this , actualIOBehavior , connectToken ) . ConfigureAwait ( false ) ;
647
+ return await pool . GetSessionAsync ( this , startTickCount , actualIOBehavior , connectToken ) . ConfigureAwait ( false ) ;
646
648
}
647
649
else
648
650
{
@@ -653,7 +655,7 @@ private async ValueTask<ServerSession> CreateSessionAsync(ConnectionPool? pool,
653
655
var session = new ServerSession ( ) ;
654
656
session . OwningConnection = new WeakReference < MySqlConnection > ( this ) ;
655
657
Log . Info ( "Created new non-pooled Session{0}" , session . Id ) ;
656
- await session . ConnectAsync ( connectionSettings , loadBalancer , actualIOBehavior , connectToken ) . ConfigureAwait ( false ) ;
658
+ await session . ConnectAsync ( connectionSettings , startTickCount , loadBalancer , actualIOBehavior , connectToken ) . ConfigureAwait ( false ) ;
657
659
return session ;
658
660
}
659
661
}
@@ -662,6 +664,10 @@ private async ValueTask<ServerSession> CreateSessionAsync(ConnectionPool? pool,
662
664
var messageSuffix = ( pool ? . IsEmpty ?? false ) ? " All pooled connections are in use." : "" ;
663
665
throw new MySqlException ( MySqlErrorCode . UnableToConnectToHost , "Connect Timeout expired." + messageSuffix , ex ) ;
664
666
}
667
+ catch ( MySqlException ex ) when ( timeoutSource ? . IsCancellationRequested ?? false )
668
+ {
669
+ throw new MySqlException ( MySqlErrorCode . UnableToConnectToHost , "Connect Timeout expired." , ex ) ;
670
+ }
665
671
finally
666
672
{
667
673
linkedSource ? . Dispose ( ) ;
0 commit comments