sklose / NCalc2

expression evaluator for .NET with built-in compiler
MIT License
170 stars 58 forks source link

Index was outside the bounds of the array. at NCalc.Expression.Evaluate() #39

Open enshivam opened 4 years ago

enshivam commented 4 years ago

In any random and rare scenario, Getting Index was outside the bounds of the array. at NCalc.Expression.Evaluate() while only evaluating very simple expression, or boolean conversions. Using .net core 3.0.

Issue doesn't seem to appear while using EvaluationOptions.NoCache.

Any pointers on if I may be doing something wrong? Any way to identify the detailed trace atleast?

GDeGruyter commented 4 years ago

Same issue here. We ran on .net core 2.2 and saw no issues. Since we upgraded to .net core 3.0 we are experiencing the issues as described. I also saw 'Object reference not set to an instance object' on Expression.CleanCache(), which confirms the issue could be related to the cache. I will test with 'EvalualationOptions.NoCache' as suggested by @enshivam. I can also confirm the issue is random so hard to ack the relationship with the cache.

Bykiev commented 7 months ago

I've tried to reproduce the issue with no luck

eugenca commented 7 months ago

@Bykiev I got some occasional test run error on that test recently when running it first time, then it disappeared

Bykiev commented 7 months ago

@Bykiev I got some occasional test run error on that test recently when running it first time, then it disappeared

What is a target framework? I've tried to reproduce the issue with no luck. The cache will be slightly changed if https://github.com/sklose/NCalc2/pull/98 will be merged.

Bykiev commented 7 months ago

From the docs:

For modifications and write operations to the dictionary, ConcurrentDictionary<TKey,TValue> uses fine-grained locking to ensure thread safety (read operations on the dictionary are performed in a lock-free manner). The addValueFactory and updateValueFactory delegates may be executed multiple times to verify the value was added or updated as expected. However, they are called outside the locks to avoid the problems that can arise from executing unknown code under a lock. Therefore, AddOrUpdate is not atomic with regards to all other operations on the ConcurrentDictionary<TKey,TValue> class.