public void ClearCachedData() { // reset the default culture values s_userDefaultCulture = GetUserDefaultCulture(); s_userDefaultUICulture = GetUserDefaultUICulture(); RegionInfo.s_currentRegionInfo = null; #pragma warning disable 0618 // disable the obsolete warning TimeZone.ResetTimeZone(); #pragma warning restore 0618 TimeZoneInfo.ClearCachedData(); s_LcidCachedCultures = null; s_NameCachedCultures = null; CultureData.ClearCachedData(); }
// Helper function both both overloads of GetCachedReadOnlyCulture. If lcid is 0, we use the name. // If lcid is -1, use the altName and create one of those special SQL cultures. internal static CultureInfo GetCultureInfoHelper(int lcid, string name, string altName) { // retval is our return value. CultureInfo retval; // Temporary hashtable for the names. StringCultureInfoDictionary tempNameHT = s_NameCachedCultures; if (name != null) { name = CultureData.AnsiToLower(name); } if (altName != null) { altName = CultureData.AnsiToLower(altName); } // We expect the same result for both hashtables, but will test individually for added safety. if (tempNameHT == null) { tempNameHT = new StringCultureInfoDictionary(); } else { // If we are called by name, check if the object exists in the hashtable. If so, return it. if (lcid == -1 || lcid == 0) { bool ret; lock (m_lock) { ret = tempNameHT.TryGetValue(lcid == 0 ? name : name + '\xfffd' + altName, out retval); } if (ret && retval != null) { return(retval); } } } // Next, the Lcid table. StringLcidDictionary tempLcidHT = s_LcidCachedCultures; if (tempLcidHT == null) { // Case insensitive is not an issue here, save the constructor call. tempLcidHT = new StringLcidDictionary(); } else { // If we were called by Lcid, check if the object exists in the table. If so, return it. if (lcid > 0) { bool ret; lock (m_lock) { ret = tempLcidHT.TryGetValue(lcid, out retval); } if (ret && retval != null) { return(retval); } } } // We now have two temporary hashtables and the desired object was not found. // We'll construct it. We catch any exceptions from the constructor call and return null. try { switch (lcid) { case -1: // call the private constructor retval = new CultureInfo(name, altName); break; case 0: retval = new CultureInfo(name, false); break; default: retval = new CultureInfo(lcid, false); break; } } catch (ArgumentException) { return(null); } // Set it to read-only retval.m_isReadOnly = true; if (lcid == -1) { lock (m_lock) { // This new culture will be added only to the name hash table. tempNameHT[name + '\xfffd' + altName] = retval; } // when lcid == -1 then TextInfo object is already get created and we need to set it as read only. retval.TextInfo.SetReadOnlyState(true); } else if (lcid == 0) { // Remember our name (as constructed). Do NOT use alternate sort name versions because // we have internal state representing the sort. (So someone would get the wrong cached version) string newName = CultureData.AnsiToLower(retval.m_name); // We add this new culture info object to both tables. lock (m_lock) { tempNameHT[newName] = retval; } } else { lock (m_lock) { tempLcidHT[lcid] = retval; } } // Copy the two hashtables to the corresponding member variables. This will potentially overwrite // new tables simultaneously created by a new thread, but maximizes thread safety. if (-1 != lcid) { // Only when we modify the lcid hash table, is there a need to overwrite. s_LcidCachedCultures = tempLcidHT; } s_NameCachedCultures = tempNameHT; // Finally, return our new CultureInfo object. return(retval); }
// Helper function both both overloads of GetCachedReadOnlyCulture. internal static CultureInfo GetCultureInfoHelper(string name) { // There is a race condition in this code with the side effect that the second thread's value // clobbers the first in the dictionary. This is an acceptable race since the CultureInfo objects // are content equal (but not reference equal). Since we make no guarantees there, this race is // acceptable. // retval is our return value. CultureInfo retval; if (name == null) { return null; } // Temporary hashtable for the names. StringCultureInfoDictionary tempNameHT = s_NameCachedCultures; name = CultureData.AnsiToLower(name); // We expect the same result for both hashtables, but will test individually for added safety. if (tempNameHT == null) { tempNameHT = new StringCultureInfoDictionary(); } else { bool ret; lock (m_lock) { ret = tempNameHT.TryGetValue(name, out retval); } if (ret && retval != null) { return retval; } } try { retval = new CultureInfo(name, false); } catch (ArgumentException) { return null; } // Set it to read-only retval.m_isReadOnly = true; // Remember our name (as constructed). Do NOT use alternate sort name versions because // we have internal state representing the sort. (So someone would get the wrong cached version) string newName = CultureData.AnsiToLower(retval.m_name); // We add this new culture info object to both tables. lock (m_lock) { tempNameHT[newName] = retval; } s_NameCachedCultures = tempNameHT; // Finally, return our new CultureInfo object. return retval; }
// Helper function both both overloads of GetCachedReadOnlyCulture. If lcid is 0, we use the name. // If lcid is -1, use the altName and create one of those special SQL cultures. internal static CultureInfo GetCultureInfoHelper(int lcid, string name, string altName) { // retval is our return value. CultureInfo retval; // Temporary hashtable for the names. StringCultureInfoDictionary tempNameHT = s_NameCachedCultures; if (name != null) { name = CultureData.AnsiToLower(name); } if (altName != null) { altName = CultureData.AnsiToLower(altName); } // We expect the same result for both hashtables, but will test individually for added safety. if (tempNameHT == null) { tempNameHT = new StringCultureInfoDictionary(); } else { // If we are called by name, check if the object exists in the hashtable. If so, return it. if (lcid == -1 || lcid == 0) { bool ret; lock (m_lock) { ret = tempNameHT.TryGetValue(lcid == 0 ? name : name + '\xfffd' + altName, out retval); } if (ret && retval != null) { return retval; } } } // Next, the Lcid table. StringLcidDictionary tempLcidHT = s_LcidCachedCultures; if (tempLcidHT == null) { // Case insensitive is not an issue here, save the constructor call. tempLcidHT = new StringLcidDictionary(); } else { // If we were called by Lcid, check if the object exists in the table. If so, return it. if (lcid > 0) { bool ret; lock (m_lock) { ret = tempLcidHT.TryGetValue(lcid, out retval); } if (ret && retval != null) { return retval; } } } // We now have two temporary hashtables and the desired object was not found. // We'll construct it. We catch any exceptions from the constructor call and return null. try { switch (lcid) { case -1: // call the private constructor retval = new CultureInfo(name, altName); break; case 0: retval = new CultureInfo(name, false); break; default: retval = new CultureInfo(lcid, false); break; } } catch (ArgumentException) { return null; } // Set it to read-only retval.m_isReadOnly = true; if (lcid == -1) { lock (m_lock) { // This new culture will be added only to the name hash table. tempNameHT[name + '\xfffd' + altName] = retval; } // when lcid == -1 then TextInfo object is already get created and we need to set it as read only. retval.TextInfo.SetReadOnlyState(true); } else if (lcid == 0) { // Remember our name (as constructed). Do NOT use alternate sort name versions because // we have internal state representing the sort. (So someone would get the wrong cached version) string newName = CultureData.AnsiToLower(retval.m_name); // We add this new culture info object to both tables. lock (m_lock) { tempNameHT[newName] = retval; } } else { lock (m_lock) { tempLcidHT[lcid] = retval; } } // Copy the two hashtables to the corresponding member variables. This will potentially overwrite // new tables simultaneously created by a new thread, but maximizes thread safety. if (-1 != lcid) { // Only when we modify the lcid hash table, is there a need to overwrite. s_LcidCachedCultures = tempLcidHT; } s_NameCachedCultures = tempNameHT; // Finally, return our new CultureInfo object. return retval; }
public void ClearCachedData() { s_userDefaultCulture = null; RegionInfo.s_currentRegionInfo = null; #pragma warning disable 0618 // disable the obsolete warning TimeZone.ResetTimeZone(); #pragma warning restore 0618 TimeZoneInfo.ClearCachedData(); s_LcidCachedCultures = null; s_NameCachedCultures = null; CultureData.ClearCachedData(); }
// Helper function both both overloads of GetCachedReadOnlyCulture. internal static CultureInfo GetCultureInfoHelper(string name) { // There is a race condition in this code with the side effect that the second thread's value // clobbers the first in the dictionary. This is an acceptable race since the CultureInfo objects // are content equal (but not reference equal). Since we make no guarantees there, this race is // acceptable. // retval is our return value. CultureInfo retval; if (name == null) { return(null); } // Temporary hashtable for the names. StringCultureInfoDictionary tempNameHT = s_NameCachedCultures; name = CultureData.AnsiToLower(name); // We expect the same result for both hashtables, but will test individually for added safety. if (tempNameHT == null) { tempNameHT = new StringCultureInfoDictionary(); } else { bool ret; lock (m_lock) { ret = tempNameHT.TryGetValue(name, out retval); } if (ret && retval != null) { return(retval); } } try { retval = new CultureInfo(name, false); } catch (ArgumentException) { return(null); } // Set it to read-only retval.m_isReadOnly = true; // Remember our name (as constructed). Do NOT use alternate sort name versions because // we have internal state representing the sort. (So someone would get the wrong cached version) string newName = CultureData.AnsiToLower(retval.m_name); // We add this new culture info object to both tables. lock (m_lock) { tempNameHT[newName] = retval; } s_NameCachedCultures = tempNameHT; // Finally, return our new CultureInfo object. return(retval); }