-
-
Notifications
You must be signed in to change notification settings - Fork 394
Closed
Labels
Description
When doing evaluations in parallel in different threads it somehow seem that the values from the different evaluations conflict with each other and are used in unintended ways. I.e. variable value from one thread is used in another thread.
Issue is introduced in this change set
Improve Performance (#349)
in version 2.19.
And it can be reproduced with this unit test which passes in version 2.18 but not in 2.19.
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using NUnit.Framework;
namespace DynamicExpresso.UnitTest
{
[TestFixture]
public class ThreadingTest
{
private void DynamicExpresso_Interpreter_Eval1()
{
var parser = new Interpreter();
parser.SetVariable("C0", 0.4731765);
parser.SetVariable("x", 50);
Assert.That(parser.Identifiers.First(i => i.Name == "C0").Expression.ToString(), Is.EqualTo("0.4731765"));
Assert.That(parser.Identifiers.First(i => i.Name == "x").Expression.ToString(), Is.EqualTo("50"));
var result = parser.Eval<double>("x*C0");
Assert.That(result, Is.EqualTo(23.658825));
}
private void DynamicExpresso_Interpreter_Eval2()
{
var parser = new Interpreter();
parser.SetVariable("C0", 0.4731765);
parser.SetVariable("y", 1080);
Assert.That(parser.Identifiers.First(i => i.Name == "C0").Expression.ToString(), Is.EqualTo("0.4731765"));
Assert.That(parser.Identifiers.First(i => i.Name == "y").Expression.ToString(), Is.EqualTo("1080"));
var result = parser.Eval<double>("y/C0");
Assert.That(result, Is.EqualTo(2282.4464021353556));
}
private void DynamicExpresso_Interpreter_Eval_Sequence()
{
for (var i = 0; i < 10; i++)
{
DynamicExpresso_Interpreter_Eval1();
DynamicExpresso_Interpreter_Eval2();
}
}
[Test]
public async Task DynamicExpresso_Interpreter_Eval_Threading()
{
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
const int noOfTasks = 5;
var tasksToRun = new List<Task>();
for (var i = 0; i < noOfTasks; i++)
{
var taskToRunLater = new Task(() => DynamicExpresso_Interpreter_Eval_Sequence());
tasksToRun.Add(taskToRunLater);
}
foreach (var taskToRunLater in tasksToRun)
{
taskToRunLater.Start();
}
foreach (var taskToRunLater in tasksToRun)
{
await taskToRunLater;
}
}
}
}