Skip to content

Commit b6111ed

Browse files
authored
Merge pull request #104 from ZeekoZhu/fix/get-value-async-blocking
Fix GetValueAsync concurrent issue
2 parents f0b2f5f + 7ee81fa commit b6111ed

File tree

6 files changed

+365
-121
lines changed

6 files changed

+365
-121
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ packages/*/
1010
project.lock.json
1111
/publish/*.bat
1212
.vs/
13+
.idea

Enyim.Caching/Enyim.Caching.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<Description>EnyimMemcachedCore is a Memcached client library for .NET Core. Usage: Add services.AddEnyimMemcached(...) and app.UseEnyimMemcached() in Startup. Add IMemcachedClient into constructor.</Description>
5-
<VersionPrefix>2.2.0-beta1</VersionPrefix>
5+
<VersionPrefix>2.1.14</VersionPrefix>
66
<Authors>cnblogs.com</Authors>
77
<TargetFramework>netstandard2.0</TargetFramework>
88
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>

Enyim.Caching/FastActivator.cs

+43-37
Original file line numberDiff line numberDiff line change
@@ -9,48 +9,54 @@
99

1010
namespace Enyim.Reflection
1111
{
12-
/// <summary>
13-
/// <para>Implements a very fast object factory for dynamic object creation. Dynamically generates a factory class which will use the new() constructor of the requested type.</para>
14-
/// <para>Much faster than using Activator at the price of the first invocation being significantly slower than subsequent calls.</para>
15-
/// </summary>
16-
public static class FastActivator
17-
{
18-
private static Dictionary<Type, Func<object>> factoryCache = new Dictionary<Type, Func<object>>();
12+
/// <summary>
13+
/// <para>Implements a very fast object factory for dynamic object creation. Dynamically generates a factory class which will use the new() constructor of the requested type.</para>
14+
/// <para>Much faster than using Activator at the price of the first invocation being significantly slower than subsequent calls.</para>
15+
/// </summary>
16+
public static class FastActivator
17+
{
18+
private static Dictionary<Type, Func<object>> factoryCache = new Dictionary<Type, Func<object>>();
1919

20-
/// <summary>
21-
/// Creates an instance of the specified type using a generated factory to avoid using Reflection.
22-
/// </summary>
23-
/// <typeparam name="T">The type to be created.</typeparam>
24-
/// <returns>The newly created instance.</returns>
25-
public static T Create<T>()
26-
{
27-
return TypeFactory<T>.Create();
28-
}
20+
/// <summary>
21+
/// Creates an instance of the specified type using a generated factory to avoid using Reflection.
22+
/// </summary>
23+
/// <typeparam name="T">The type to be created.</typeparam>
24+
/// <returns>The newly created instance.</returns>
25+
public static T Create<T>()
26+
{
27+
return TypeFactory<T>.Create();
28+
}
2929

30-
/// <summary>
31-
/// Creates an instance of the specified type using a generated factory to avoid using Reflection.
32-
/// </summary>
33-
/// <param name="type">The type to be created.</param>
34-
/// <returns>The newly created instance.</returns>
35-
public static object Create(Type type)
36-
{
37-
Func<object> f;
30+
/// <summary>
31+
/// Creates an instance of the specified type using a generated factory to avoid using Reflection.
32+
/// </summary>
33+
/// <param name="type">The type to be created.</param>
34+
/// <returns>The newly created instance.</returns>
35+
public static object Create(Type type)
36+
{
37+
Func<object> f;
3838

39-
if (!factoryCache.TryGetValue(type, out f))
40-
lock (factoryCache)
41-
if (!factoryCache.TryGetValue(type, out f))
42-
{
43-
factoryCache[type] = f = Expression.Lambda<Func<object>>(Expression.New(type)).Compile();
44-
}
39+
if (!factoryCache.TryGetValue(type, out f))
40+
{
41+
lock (factoryCache)
42+
if (!factoryCache.TryGetValue(type, out f))
43+
{
44+
f = Expression.Lambda<Func<object>>(Expression.New(type)).Compile();
45+
if (f != null)
46+
{
47+
factoryCache[type] = f;
48+
}
49+
}
50+
}
4551

46-
return f();
47-
}
52+
return f();
53+
}
4854

49-
private static class TypeFactory<T>
50-
{
51-
public static readonly Func<T> Create = Expression.Lambda<Func<T>>(Expression.New(typeof(T))).Compile();
52-
}
53-
}
55+
private static class TypeFactory<T>
56+
{
57+
public static readonly Func<T> Create = Expression.Lambda<Func<T>>(Expression.New(typeof(T))).Compile();
58+
}
59+
}
5460
}
5561

5662
#region [ License information ]

Enyim.Caching/Memcached/AsyncSocketHelper.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -269,12 +269,12 @@ private void BeginReceive()
269269
{
270270
this.readInProgressEvent.Reset();
271271

272-
if (this.socket.socket.ReceiveAsync(this.readEvent))
272+
if (this.socket._socket.ReceiveAsync(this.readEvent))
273273
{
274274
// wait until the timeout elapses, then abort this reading process
275275
// EndREceive will be triggered sooner or later but its timeout
276276
// may be higher than our read timeout, so it's not reliable
277-
if (!readInProgressEvent.WaitOne(this.socket.socket.ReceiveTimeout))
277+
if (!readInProgressEvent.WaitOne(this.socket._socket.ReceiveTimeout))
278278
this.AbortReadAndTryPublishError(false);
279279

280280
return;
@@ -293,7 +293,7 @@ void AsyncReadCompleted(object sender, SocketAsyncEventArgs e)
293293
private void AbortReadAndTryPublishError(bool markAsDead)
294294
{
295295
if (markAsDead)
296-
this.socket.isAlive = false;
296+
this.socket._isAlive = false;
297297

298298
// we've been already aborted, so quit
299299
// both the EndReceive and the wait on the event can abort the read

0 commit comments

Comments
 (0)