Closed mgoutrie closed 2 years ago
Hi mgoutrie,
Thanks for pointing this out!
I was not aware that Dictionary
was not thread-safe!
Just swapped the Dictionary
with ConcurrentDictionary
and everything seems to work.
Then unittest you created is now working! If you have time I would very much appreciated if you would update to the newest version and test it out that it is also working in your system.
Hi Mads, Thanks a lot for the very quick response. And thanks for this library which saved me a lot o headaches.
I can prove, that the problem is not reproducible anymore.
But unfortunately, when using the current master branch (commit 7d16012), I came across an inconsistent calculation:
[TestMethod]
public void ConsistentEqualsOperations()
{
var voltMinutes = new BaseUnit(2.0, new EngineeringUnits.UnitSystem(ElectricPotentialUnit.Volt * DurationUnit.Minute, "V\u00b7min"));
var weber = EngineeringUnits.MagneticFlux.FromWeber(2 * 60);
Assert.IsTrue(voltMinutes == weber);
Assert.IsTrue(weber == voltMinutes);
Assert.IsTrue(weber.Equals(voltMinutes));
Assert.IsTrue(voltMinutes.Equals(weber));
Assert.AreEqual(0, weber.CompareTo(voltMinutes));
// The following assertion fails:
Assert.AreEqual(0, voltMinutes.CompareTo(weber));
}
My expectation was (weber.CompareTo(voltMinutes) == 0) <=> (voltMinutes.CompareTo(weber) == 0)
I suspect the calculation of
private decimal ConvertValueInto(BaseUnit From)
{
return (decimal)ConvertionFactor(From) * NEWValue;
}
introduces a numeric error. Perhaps it should be better
return (decimal)(ConvertionFactor(From) * (Fraction)NEWValue);
which is consistent with the calculation in BaseUnit.GetValueAs()
which is used in the equality operator.
PS: perhaps the calculation of BaseUnit.baseValue
should be changed in a similar way, but I'm not really sure.
With best regards, Mike
You make my job really easy when you both find the bugs and the solutions! :-D
Thanks a lot!
If you find other bugs or have feature requests, just let me know!
I have added your test and update the nuget!
Thanks a lot for your fast responses!
Indeed I may have two other topics, but I'll have to prepare this next week. For the moment I'd close this issue as it is fully resolved :)
The access to the caches of the multiplied and divided units is not protected from concurrent access. I had sporadic errors when running unit tests involving unit calculations/unit initializations. I reduced the problem to the followinf unit test which fails with a high probability:
Observed behavior
I had another test with random units which showed some different errors, e.g.
Expected behavior: No exception when doing unit calculations in different threads.