-
Notifications
You must be signed in to change notification settings - Fork 373
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Concurrency checks in UnitValueAbbreviationLookup no longer working correctly #1303
Labels
Comments
angularsen
added a commit
that referenced
this issue
Aug 12, 2023
Fixes #1303 Change back to `ConcurrencyDictionary`, there was a subtle write-on-read when loading the initial values that could throw. ``` System.InvalidOperationException: Operations that change non-concurrent collections must have exclusive access. A concurrent update was performed on this collection and corrupted its state. The collection's state is no longer correct. at System.Collections.Generic.Dictionary`2.FindValue(TKey key) at System.Collections.Generic.Dictionary`2.TryGetValue(TKey key, TValue& value) at UnitsNet.UnitAbbreviationsCache.GetAbbreviations(UnitInfo unitInfo, IFormatProvider formatProvider) at UnitsNet.UnitAbbreviationsCache.TryGetUnitAbbreviations(Type unitType, Int32 unitValue, IFormatProvider formatProvider, String[]& abbreviations) at UnitsNet.UnitAbbreviationsCache.GetUnitAbbreviations(Type unitType, Int32 unitValue, IFormatProvider formatProvider) ```
angularsen
added a commit
that referenced
this issue
Aug 12, 2023
Fixes #1303 Change back to `ConcurrencyDictionary`, there was a subtle write-on-read when loading the initial values that could throw in `UnitAbbreviationsCache.GetAbbreviations()`: ```cs if (!AbbreviationsMap.TryGetValue(key, out IReadOnlyList<string>? abbreviations)) AbbreviationsMap[key] = abbreviations = ReadAbbreviationsFromResourceFile(unitInfo.QuantityName, unitInfo.PluralName, culture); ``` ``` System.InvalidOperationException: Operations that change non-concurrent collections must have exclusive access. A concurrent update was performed on this collection and corrupted its state. The collection's state is no longer correct. at System.Collections.Generic.Dictionary`2.FindValue(TKey key) at System.Collections.Generic.Dictionary`2.TryGetValue(TKey key, TValue& value) at UnitsNet.UnitAbbreviationsCache.GetAbbreviations(UnitInfo unitInfo, IFormatProvider formatProvider) at UnitsNet.UnitAbbreviationsCache.TryGetUnitAbbreviations(Type unitType, Int32 unitValue, IFormatProvider formatProvider, String[]& abbreviations) at UnitsNet.UnitAbbreviationsCache.GetUnitAbbreviations(Type unitType, Int32 unitValue, IFormatProvider formatProvider) ```
I was just checking what dev team would first catch this subtle racing condition 🧐 Well done! 🥳 Just kidding, nice catch. This part of the code has had quite a bit of refactoring lately. Nuget should be out shortly. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Describe the bug
The concurrency checks in UnitAbbreviationsCache are no longer working correctly.
Specificially, we sometimes see this error in our tests:
To Reproduce
Set up a concurrency situation (multiple threads) with e.g.
UnitsNetSetup.Default.UnitAbbreviations.GetDefaultAbbreviation(unit, culture)
Expected behavior
Should never throw Exception.
Additional context
I see from the history in this file that at one point a ConcurrencyDictionary was used, but that it was later removed.
Perhaps re-introduce this, or simply add correct locking around access to the AbbreviationsMap object.
The text was updated successfully, but these errors were encountered: