@@ -65,11 +65,7 @@ public abstract class TcpSocketClientBase(SocketClientOptions options) : ITcpSoc
6565 private CancellationTokenSource ? _receiveCancellationTokenSource ;
6666 private CancellationTokenSource ? _autoConnectTokenSource ;
6767
68- #if NET9_0_OR_GREATER
69- private readonly Lock _lock = new ( ) ;
70- #else
71- private readonly object _lock = new ( ) ;
72- #endif
68+ private readonly SemaphoreSlim _semaphoreSlim = new ( 1 , 1 ) ;
7369
7470 /// <summary>
7571 /// <inheritdoc/>
@@ -84,12 +80,22 @@ public async ValueTask<bool> ConnectAsync(IPEndPoint endPoint, CancellationToken
8480 return true ;
8581 }
8682
87- lock ( _lock )
83+ var connectionToken = GenerateConnectionToken ( token ) ;
84+ try
8885 {
89- if ( IsConnected )
90- {
91- return true ;
92- }
86+ await _semaphoreSlim . WaitAsync ( connectionToken ) . ConfigureAwait ( false ) ;
87+ }
88+ catch ( OperationCanceledException )
89+ {
90+ // 如果信号量等待被取消,则直接返回 IsConnected
91+ // 不管是超时还是被取消,都不需要重连,肯定有其他线程在连接中
92+ return IsConnected ;
93+ }
94+
95+ if ( IsConnected )
96+ {
97+ _semaphoreSlim . Release ( ) ;
98+ return true ;
9399 }
94100
95101 var reconnect = true ;
@@ -99,7 +105,7 @@ public async ValueTask<bool> ConnectAsync(IPEndPoint endPoint, CancellationToken
99105
100106 try
101107 {
102- ret = await ConnectCoreAsync ( SocketClientProvider , endPoint , token ) ;
108+ ret = await ConnectCoreAsync ( SocketClientProvider , endPoint , connectionToken ) ;
103109 }
104110 catch ( OperationCanceledException ex )
105111 {
@@ -118,10 +124,14 @@ public async ValueTask<bool> ConnectAsync(IPEndPoint endPoint, CancellationToken
118124 Log ( LogLevel . Error , ex , $ "TCP Socket connection failed from { LocalEndPoint } to { endPoint } ") ;
119125 }
120126
127+ // 释放信号量
128+ _semaphoreSlim . Release ( ) ;
129+
121130 if ( ! ret && reconnect )
122131 {
123132 Reconnect ( ) ;
124133 }
134+
125135 return ret ;
126136 }
127137
@@ -153,14 +163,7 @@ private async ValueTask<bool> ConnectCoreAsync(ISocketClientProvider provider, I
153163 _localEndPoint = Options . LocalEndPoint ;
154164 _remoteEndPoint = endPoint ;
155165
156- var connectionToken = token ;
157- if ( Options . ConnectTimeout > 0 )
158- {
159- // 设置连接超时时间
160- var connectTokenSource = new CancellationTokenSource ( options . ConnectTimeout ) ;
161- connectionToken = CancellationTokenSource . CreateLinkedTokenSource ( token , connectTokenSource . Token ) . Token ;
162- }
163- var ret = await provider . ConnectAsync ( endPoint , connectionToken ) ;
166+ var ret = await provider . ConnectAsync ( endPoint , token ) ;
164167
165168 if ( ret )
166169 {
@@ -174,6 +177,18 @@ private async ValueTask<bool> ConnectCoreAsync(ISocketClientProvider provider, I
174177 return ret ;
175178 }
176179
180+ private CancellationToken GenerateConnectionToken ( CancellationToken token )
181+ {
182+ var connectionToken = token ;
183+ if ( Options . ConnectTimeout > 0 )
184+ {
185+ // 设置连接超时时间
186+ var connectTokenSource = new CancellationTokenSource ( options . ConnectTimeout ) ;
187+ connectionToken = CancellationTokenSource . CreateLinkedTokenSource ( token , connectTokenSource . Token ) . Token ;
188+ }
189+ return connectionToken ;
190+ }
191+
177192 /// <summary>
178193 /// <inheritdoc/>
179194 /// </summary>
0 commit comments