'Thread locking not behaving properly when using appSettings to track whether complete

I have a scenario where I need to override some application settings when an ASP.Net site spins up (and never again until the application pool resets.)

Here is the rough implementation:

        private object _lockObject = new object();

        private void OverrideSettings()
        {
            if (!ConfigurationUtility.GetAppSettingsValue<bool>(SETUPCOMPLETEAPPSETTINGKEY))
            {
                lock (_lockObject)
                {
                    if (!ConfigurationUtility.GetAppSettingsValue<bool>(SETUPCOMPLETEAPPSETTINGKEY))
                    {
                        // snip...
                        ConfigurationManager.AppSettings.Set(SETUPCOMPLETEAPPSETTINGKEY, bool.TrueString);    
                    }
                }
            }
        }

Usually, this works fine, but occasionally (when under load and the application pool resets,) I receive the following:

Exception information: Exception type: ArgumentException Exception message: Item has already been added. Key in dictionary: 'OverrideOfAppSettingsComplete' Key being added: 'OverrideOfAppSettingsComplete' at System.Collections.Hashtable.Insert(Object key, Object nvalue, Boolean add) at System.Collections.Specialized.NameObjectCollectionBase.BaseAdd(String name, Object value) at Modules.LoadOverriddenSiteSettingsModule`1.OverrideSettings() in c:\Modules\LoadOverriddenSiteSettingsModule.cs:line 203

This implies that either two threads entered the lock at the same time or that setting the "completed" application setting didn't take effect.

Does anyone have any insight, or is there a better way to accomplish this?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source