Search code examples
c#performanceconfigurationapp-configappsettings

Poor performance when modifying appSettings


I have an application in which I create a TreeView from the values of a database and display it with checkboxes. Now I want to write the selected values into the appSettings. I tried to do this with this code. But the performance is so bad, that this probably can't be the right way. How can I solve it better?

public static void SearchAndSaveSelectedNodes(TreeNodeCollection nodes)
{
    foreach (TreeNode n in nodes)
    {
        DeleteSetting(n.Name);

        if (n.Checked)
        {
            UpdateSetting(n.Name, n.Name + "@" + n.FullPath);
        }
        SearchAndSaveSelectedNodes(n.Nodes);
    }
}

public static void DeleteSetting(string key)
{
    System.Configuration.Configuration config = `ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);`
    config.AppSettings.Settings.Remove(key);
    config.Save(ConfigurationSaveMode.Modified);
    ConfigurationManager.RefreshSection("appSettings");
    ConfigurationManager.RefreshSection(config.AppSettings.SectionInformation.Name);
}

public static void UpdateSetting(string key, string value)
{
    System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
    config.AppSettings.Settings.Remove(key);
    config.AppSettings.Settings.Add(key, value);
    config.Save(ConfigurationSaveMode.Modified);
    ConfigurationManager.RefreshSection("appSettings");
    ConfigurationManager.RefreshSection(config.AppSettings.SectionInformation.Name);
}

Solution

  • I believe the problem is that you open/save/refresh.. etc. the config many times, redundantly.

    I've quickly "inlined" the required calls so they're only executed when needed and added a 2nd method to make the recursive calls without opening/saving repeatedly. (UNTESTED)

    Check if that works for you.

    public static void SearchAndSaveSelectedNodes(TreeNodeCollection nodes)
    {
        // open config (only once)
        var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
    
        // make edits (recursive)
        SearchAndSaveSelectedNodesRecursive(nodes, config);
    
        // save (only once)
        config.Save(ConfigurationSaveMode.Modified);
        // (afaik there is no need to refresh the section)
    }
    
    private static void SearchAndSaveSelectedNodesRecursive(TreeNodeCollection nodes, Configuration config)
    {
        foreach (TreeNode n in nodes)
        {
            config.AppSettings.Settings.Remove(n.Name);
            if (n.Checked)
            {
                // no need to delete again here (it's already deleted)
                config.AppSettings.Settings.Add(n.Name, n.Name + "@" + n.FullPath);
            }
            SearchAndSaveSelectedNodesRecursive(n.Nodes, config);
        }
    }