From 3eec4a7297a82ecb8e30b20c7e83795f0e43981c Mon Sep 17 00:00:00 2001 From: Brian Werth Date: Mon, 7 Dec 2020 12:26:14 -0500 Subject: [PATCH 1/2] Repairing concurrent QueryFilterManager use --- .../QueryFilterManager.cs | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/shared/Z.EF.Plus.QueryFilter.Shared/QueryFilterManager.cs b/src/shared/Z.EF.Plus.QueryFilter.Shared/QueryFilterManager.cs index 447b19b9..80c6b6f1 100644 --- a/src/shared/Z.EF.Plus.QueryFilter.Shared/QueryFilterManager.cs +++ b/src/shared/Z.EF.Plus.QueryFilter.Shared/QueryFilterManager.cs @@ -6,6 +6,7 @@ // Copyright © ZZZ Projects Inc. 2014 - 2016. All rights reserved. using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; @@ -53,11 +54,11 @@ static QueryFilterManager() { EntityFrameworkManager.IsEntityFrameworkPlus = true; - CacheGenericFilterContext = new Dictionary(); + CacheGenericFilterContext = new ConcurrentDictionary(); CacheWeakFilterContext = new ConditionalWeakTable(); CacheWeakFilterQueryable = new ConditionalWeakTable(); - GlobalFilters = new Dictionary(); - GlobalInitializeFilterActions = new List>>(); + GlobalFilters = new ConcurrentDictionary(); + GlobalInitializeFilterActions = new ConcurrentBag>>(); #if NETSTANDARD2_0 && !EFCLASSIC ForceCast = true; @@ -72,15 +73,15 @@ static QueryFilterManager() /// Gets the global filters. /// The global filters. - public static Dictionary GlobalFilters { get; } + public static ConcurrentDictionary GlobalFilters { get; } /// Gets or sets the global initialize filter actions. /// The global initialize filter actions. - public static List>> GlobalInitializeFilterActions { get; set; } + public static ConcurrentBag>> GlobalInitializeFilterActions { get; set; } /// Gets or sets the dictionary containing generic filter context information for a DbContext.FullName. /// The dictionary containing generic filter context information for a DbContext.FullName. - public static Dictionary CacheGenericFilterContext { get; set; } + public static ConcurrentDictionary CacheGenericFilterContext { get; set; } /// Gets or sets the weak table containing filter context for a specified context. /// The weak table containing filter context for a specified context. @@ -100,13 +101,10 @@ public static AliasQueryFilterContext AddOrGetGenericFilterContext(DbContext con if (!CacheGenericFilterContext.TryGetValue(key, out filterContext)) { - lock (GenericFilterContextLock) + filterContext = new AliasQueryFilterContext(context, true); + if (!CacheGenericFilterContext.TryAdd(key, filterContext)) { - if (!CacheGenericFilterContext.TryGetValue(key, out filterContext)) - { - filterContext = new AliasQueryFilterContext(context, true); - CacheGenericFilterContext.Add(key, filterContext); - } + CacheGenericFilterContext.TryGetValue(key, out filterContext); } } @@ -180,7 +178,10 @@ public static AliasBaseQueryFilter Filter(object key, Func, IQu #else filter = new QueryFilter(null, queryFilter) { IsDefaultEnabled = isEnabled }; #endif - GlobalFilters.Add(key, filter); + if (!GlobalFilters.TryAdd(key, filter)) + { + GlobalFilters.TryGetValue(key, out filter); + } } return filter; From 408c92fc29115e20b5e88b047d12ae6fdea27429 Mon Sep 17 00:00:00 2001 From: Brian Werth Date: Mon, 7 Dec 2020 12:34:26 -0500 Subject: [PATCH 2/2] Changing QueryFilterManager concurrency dictionary use from TryGet/TryAdd/TryGet to TryGet/GetOrAdd --- .../Z.EF.Plus.QueryFilter.Shared/QueryFilterManager.cs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/shared/Z.EF.Plus.QueryFilter.Shared/QueryFilterManager.cs b/src/shared/Z.EF.Plus.QueryFilter.Shared/QueryFilterManager.cs index 80c6b6f1..6d19ccf6 100644 --- a/src/shared/Z.EF.Plus.QueryFilter.Shared/QueryFilterManager.cs +++ b/src/shared/Z.EF.Plus.QueryFilter.Shared/QueryFilterManager.cs @@ -102,10 +102,7 @@ public static AliasQueryFilterContext AddOrGetGenericFilterContext(DbContext con if (!CacheGenericFilterContext.TryGetValue(key, out filterContext)) { filterContext = new AliasQueryFilterContext(context, true); - if (!CacheGenericFilterContext.TryAdd(key, filterContext)) - { - CacheGenericFilterContext.TryGetValue(key, out filterContext); - } + filterContext = CacheGenericFilterContext.GetOrAdd(key, filterContext); } return filterContext; @@ -178,10 +175,7 @@ public static AliasBaseQueryFilter Filter(object key, Func, IQu #else filter = new QueryFilter(null, queryFilter) { IsDefaultEnabled = isEnabled }; #endif - if (!GlobalFilters.TryAdd(key, filter)) - { - GlobalFilters.TryGetValue(key, out filter); - } + filter = GlobalFilters.GetOrAdd(key, filter); } return filter;