Skip to content

Commit b61bc9b

Browse files
committed
Make FormatNCalcCache thread-local (#428)
1 parent eb16f9a commit b61bc9b

File tree

2 files changed

+12
-13
lines changed

2 files changed

+12
-13
lines changed

src/SmartFormat.Extensions.LogiCalc/LogiCalcFormatter.cs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,12 @@ namespace SmartFormat.Extensions;
2626
/// </remarks>
2727
public class LogiCalcFormatter : IFormatter
2828
{
29-
// Todo: Make the cache static and thread-safe?
3029
private readonly Dictionary<string, object?> _parameters = new(50);
3130

32-
[ThreadStatic] // creates isolated versions of the cache dictionary in each thread
33-
private static Dictionary<string, (Format Format, NCalc.Domain.LogicalExpression LogExpr)>? _formatNCalcCache;
31+
private static readonly
32+
System.Threading.ThreadLocal<Dictionary<string, (Format Format, NCalc.Domain.LogicalExpression LogExpr)>>
33+
FormatNCalcCache = new(() =>
34+
new Dictionary<string, (Format Format, NCalc.Domain.LogicalExpression LogExpr)>(100));
3435

3536
///<inheritdoc/>
3637
public string Name { get; set; } = "calc";
@@ -58,21 +59,19 @@ public class LogiCalcFormatter : IFormatter
5859
///<inheritdoc />
5960
public bool TryEvaluateFormat(IFormattingInfo formattingInfo)
6061
{
61-
_formatNCalcCache ??= new Dictionary<string, (Format, NCalc.Domain.LogicalExpression)>(100);
62-
6362
var format = formattingInfo.Format;
6463
if (format == null) return false;
65-
64+
6665
var fi = (FormattingInfo) formattingInfo;
67-
66+
6867
_parameters.Clear();
6968
using var expressionValue = CreateNCalcExpression(fi, _parameters);
70-
69+
7170
try
7271
{
7372
// Create Format and LogicalExpression if they don't exist for the Placeholder
7473
var key = formattingInfo.Placeholder!.ToString();
75-
if (!_formatNCalcCache.TryGetValue(key, out var cache))
74+
if (!FormatNCalcCache.Value!.TryGetValue(key, out var cache))
7675
{
7776
cache.Format = formattingInfo.FormatDetails.Formatter.Parser.ParseFormat(
7877
$"{{,{formattingInfo.Alignment}:d:{formattingInfo.FormatterOptions}}}");
@@ -86,8 +85,8 @@ public bool TryEvaluateFormat(IFormattingInfo formattingInfo)
8685

8786
cache.LogExpr = NCalc.Factories.LogicalExpressionFactory.Create(expressionValue.ToString(),
8887
new NCalc.ExpressionContext(nCalcOptions, CultureInfo.InvariantCulture));
89-
90-
_formatNCalcCache.Add(key, cache);
88+
89+
FormatNCalcCache.Value.Add(key, cache);
9190
}
9291

9392
var nCalcExpression = new NCalc.Expression(cache.LogExpr)
@@ -110,7 +109,7 @@ public bool TryEvaluateFormat(IFormattingInfo formattingInfo)
110109
{
111110
throw new FormattingException(format, exception, format.StartIndex);
112111
}
113-
112+
114113
return true;
115114
}
116115

src/SmartFormat.Extensions.LogiCalc/SmartFormat.Extensions.LogiCalc.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ It uses extensions to provide named placeholders, localization, pluralization, g
2828
</ItemGroup>
2929

3030
<ItemGroup Condition="'$(TargetFramework)' == 'net462' or '$(TargetFramework)' == 'netStandard2.0'">
31-
<PackageReference Include="System.Memory" Version="4.5.5" />
31+
<PackageReference Include="System.Memory" Version="4.6.0" />
3232
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
3333
</ItemGroup>
3434

0 commit comments

Comments
 (0)