Skip to content

Commit 00db199

Browse files
authored
Merge pull request #245 from cnblogs/deal-with-disposed-exception
refactor: deal with socket disposed exception
2 parents 4f90f0f + 50413d3 commit 00db199

File tree

2 files changed

+82
-46
lines changed

2 files changed

+82
-46
lines changed

src/Enyim.Caching/Memcached/MemcachedNode.cs

+50-32
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
using Enyim.Caching.Configuration;
2-
using Enyim.Caching.Memcached.Protocol.Binary;
32
using Enyim.Caching.Memcached.Results;
43
using Enyim.Caching.Memcached.Results.Extensions;
5-
using Enyim.Collections;
64
using Microsoft.Extensions.Logging;
75
using System;
86
using System.Collections.Concurrent;
@@ -12,8 +10,6 @@
1210
using System.Net;
1311
using System.Net.Security;
1412
using System.Net.Sockets;
15-
using System.Runtime.Serialization;
16-
using System.Security;
1713
using System.Threading;
1814
using System.Threading.Tasks;
1915

@@ -899,49 +895,71 @@ protected internal virtual PooledSocket CreateSocket()
899895
{
900896
try
901897
{
902-
var ps = new PooledSocket(_endPoint, _config.ConnectionTimeout, _config.ReceiveTimeout, _logger,
903-
#if NET5_0_OR_GREATER
904-
_useSslStream, _useIPv6, _sslClientAuthOptions);
905-
#else
906-
_useSslStream, _useIPv6);
907-
#endif
908-
ps.Connect();
909-
return ps;
898+
return CreateSocketInternal();
910899
}
911-
catch (Exception ex)
900+
catch
912901
{
913-
_logger.LogError(ex, $"Create {nameof(PooledSocket)}");
914-
throw;
902+
try
903+
{
904+
return CreateSocketInternal();
905+
}
906+
catch (Exception ex)
907+
{
908+
LogCreateSocketError(ex, nameof(CreateSocket));
909+
throw;
910+
}
915911
}
916912
}
917913

918-
protected internal virtual async Task<PooledSocket> CreateSocketAsync()
914+
private PooledSocket CreateSocketInternal()
919915
{
920-
try
921-
{
922-
var ps = new PooledSocket(_endPoint, _config.ConnectionTimeout, _config.ReceiveTimeout, _logger,
916+
var ps = new PooledSocket(_endPoint, _config.ConnectionTimeout, _config.ReceiveTimeout, _logger,
923917
#if NET5_0_OR_GREATER
924-
_useSslStream, _useIPv6, _sslClientAuthOptions);
918+
_useSslStream, _useIPv6, _sslClientAuthOptions);
925919
#else
926-
_useSslStream, _useIPv6);
920+
_useSslStream, _useIPv6);
927921
#endif
928-
await ps.ConnectAsync();
929-
return ps;
922+
ps.Connect();
923+
return ps;
924+
}
925+
926+
protected internal virtual async Task<PooledSocket> CreateSocketAsync()
927+
{
928+
try
929+
{
930+
return await CreateSocketInternalAsync();
930931
}
931-
catch (Exception ex)
932+
catch
932933
{
933-
var endPointStr = _endPoint.ToString().Replace("Unspecified/", string.Empty);
934-
_logger.LogError(ex, $"Failed to {nameof(CreateSocketAsync)} to {endPointStr}");
935-
throw;
934+
try
935+
{
936+
return await CreateSocketInternalAsync();
937+
}
938+
catch (Exception ex)
939+
{
940+
LogCreateSocketError(ex, nameof(CreateSocketAsync));
941+
throw;
942+
}
936943
}
937944
}
938945

939-
//protected internal virtual PooledSocket CreateSocket(IPEndPoint endpoint, TimeSpan connectionTimeout, TimeSpan receiveTimeout)
940-
//{
941-
// PooledSocket retval = new PooledSocket(endPoint, connectionTimeout, receiveTimeout);
946+
private async Task<PooledSocket> CreateSocketInternalAsync()
947+
{
948+
var ps = new PooledSocket(_endPoint, _config.ConnectionTimeout, _config.ReceiveTimeout, _logger,
949+
#if NET5_0_OR_GREATER
950+
_useSslStream, _useIPv6, _sslClientAuthOptions);
951+
#else
952+
_useSslStream, _useIPv6);
953+
#endif
954+
await ps.ConnectAsync();
955+
return ps;
956+
}
942957

943-
// return retval;
944-
//}
958+
private void LogCreateSocketError(Exception ex, string operation)
959+
{
960+
var endPointStr = _endPoint.ToString().Replace("Unspecified/", string.Empty);
961+
_logger.LogError(ex, "Failed to {operation} to {EndPoint}", operation, endPointStr);
962+
}
945963

946964
protected virtual IPooledSocketResult ExecuteOperation(IOperation op)
947965
{

src/Enyim.Caching/Memcached/PooledSocket.cs

+32-14
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ public partial class PooledSocket : IDisposable
1818
private readonly ILogger _logger;
1919

2020
private bool _isAlive;
21-
private bool _useSslStream;
22-
private bool _useIPv6;
21+
private readonly bool _useSslStream;
22+
private readonly bool _useIPv6;
2323
private Socket _socket;
24+
private bool _isSocketDisposed;
2425
private readonly EndPoint _endpoint;
2526
private readonly int _connectionTimeout;
2627

@@ -74,7 +75,7 @@ public PooledSocket(EndPoint endpoint, TimeSpan connectionTimeout, TimeSpan rece
7475
_socket = socket;
7576
}
7677

77-
public void Connect()
78+
public bool Connect()
7879
{
7980
bool success = false;
8081

@@ -86,20 +87,21 @@ void Cancel()
8687
{
8788
if (_socket != null && !_socket.Connected)
8889
{
89-
_socket.Dispose();
90-
_socket = null;
90+
DisposeSocket();
9191
}
9292
}
9393

9494
cts.Token.Register(Cancel);
9595

9696
try
9797
{
98+
if (_isSocketDisposed) return false;
9899
_socket.Connect(_endpoint);
99100
}
100101
catch (PlatformNotSupportedException)
101102
{
102103
var ep = GetIPEndPoint(_endpoint);
104+
if (_isSocketDisposed) return false;
103105
_socket.Connect(ep.Address, ep.Port);
104106
}
105107

@@ -111,8 +113,7 @@ void Cancel()
111113
}
112114
else
113115
{
114-
_socket.Dispose();
115-
_socket = null;
116+
DisposeSocket();
116117
}
117118
}
118119

@@ -133,17 +134,24 @@ void Cancel()
133134
{
134135
_inputStream = new NetworkStream(_socket);
135136
}
137+
138+
return true;
136139
}
137140
else
138141
{
139142
throw new TimeoutException($"Could not connect to {_endpoint}.");
140143
}
141144
}
142145

143-
public async Task ConnectAsync()
146+
public async Task<bool> ConnectAsync()
144147
{
145148
bool success = false;
146149

150+
if (_isSocketDisposed)
151+
{
152+
return false;
153+
}
154+
147155
try
148156
{
149157
var connTask = _socket.ConnectAsync(_endpoint);
@@ -156,8 +164,7 @@ public async Task ConnectAsync()
156164
{
157165
if (_socket != null)
158166
{
159-
_socket.Dispose();
160-
_socket = null;
167+
DisposeSocket();
161168
}
162169

163170
throw new TimeoutException($"Timeout to connect to {_endpoint}.");
@@ -166,6 +173,7 @@ public async Task ConnectAsync()
166173
catch (PlatformNotSupportedException)
167174
{
168175
var ep = GetIPEndPoint(_endpoint);
176+
if (_isSocketDisposed) return false;
169177
await _socket.ConnectAsync(ep.Address, ep.Port);
170178
}
171179

@@ -177,8 +185,7 @@ public async Task ConnectAsync()
177185
}
178186
else
179187
{
180-
_socket.Dispose();
181-
_socket = null;
188+
DisposeSocket();
182189
}
183190
}
184191

@@ -199,6 +206,8 @@ await _sslStream.AuthenticateAsClientAsync(
199206
{
200207
_inputStream = new NetworkStream(_socket);
201208
}
209+
210+
return true;
202211
}
203212
else
204213
{
@@ -333,7 +342,7 @@ protected void Dispose(bool disposing)
333342
}
334343
catch (Exception e)
335344
{
336-
_logger.LogError(nameof(PooledSocket), e);
345+
_logger.LogError(e, nameof(PooledSocket));
337346
}
338347
}
339348
else
@@ -352,8 +361,17 @@ void IDisposable.Dispose()
352361

353362
private void CheckDisposed()
354363
{
355-
if (_socket == null)
364+
if (_isSocketDisposed || _socket == null)
365+
{
356366
throw new ObjectDisposedException("PooledSocket");
367+
}
368+
}
369+
370+
private void DisposeSocket()
371+
{
372+
_isSocketDisposed = true;
373+
_socket.Dispose();
374+
_socket = null;
357375
}
358376

359377
/// <summary>

0 commit comments

Comments
 (0)