CultureInfo Caching and ClearCachedData()

Windows and the .Net Framework work a bit differently when it comes to accessing culture/locale data. Since I'm discussing Windows locales and .Net cultures I’d like to point out that culture and locales provide similar functionality. We generally refer to Windows as having locales and .Net as having cultures, and I’ll try not to mix them up J

In Windows, calls to APIs like GetLocaleInfo() always get the current data, so if someone changes a user preference for something like LOCALE_SSHORTDATE, it will be reflected in the next call to GetLocaleInfo().

In the .Net Framework, we chose a different approach. User overrides are cached when they’re used, so CultureInfo properties will return the same values even if the user change’s their preferences. .Net provides CultureInfo.ClearCachedData() which cleans out the caches so that NEW calls to new CultureInfo() or GetCultureInfo() will return updated data.

So generally the programming model in .Net is to create and use your CultureInfo’s, and then call ClearCachedData() if you want to pick up any changes to the user data. Fortunately users don’t change their preferences very often. The good thing about this design is that if you use lots of culture data, it won’t change unexpectedly. So your report won’t have MM/dd/yyyy dates suddenly change to dd/MM/yyyy dates in the middle of the report!

Note that ClearCachedData() should probably be static, however it requires an instance, so CultureInfo.CurrentCulture.ClearCachedData() is required, however that instance isn’t actually cleared. So if someone said something like:

            CultureInfo myCulture = CultureInfo.CurrentCulture
            myCulture.ClearCachedData();          

In this case, myCulture could then return different values than CultureInfo.CurrentCulture, IF the user had changed their preferences since CurrentCulture was created the first time.

In .Net v1.0 and v1.1 there was sometimes a problem with user’s changing their preferences while an application was trying to use those values. The framework caches those user preferences; however in v1.0 it did so one at a time. Now in v2.0 Whidbey they are cached in groups, so things like DateTimeFormat won’t have part older data and part newer data, they’ll all use the same set.  

If the user changes their locale and ClearCachedData is not called, then some interesting things happen. If you say a = CultureInfo.CurrentCulture and b = new CultureInfo(a), then a and b may not have the same data.  

This happens because CurrentCulture (a) may have already cached user override values. When those values are accessed with b, b will ask Windows for the user overrides. Since Windows only provides overrides for the current locale, Windows will instead provide default values. Again, this happens if the user changes their current locale, however since ClearCachedData() wasn’t called, .Net doesn’t still thinks the old culture/locale is current and still asks for overrides.

You can easily avoid these problems by not recreating culture objects. If you have a culture object, go ahead and use it. Depending on your application you can either never use ClearCachedData(), or call it occasionally at planned points where it makes sense to go ahead and update to whatever the user’s current locale information is. (Like before running a report, not in the middle of running a report J)