How can I save the settings in the IsolatedStorage

2020-03-31 08:17发布

问题:

I have Two projects in my Solution. Let's say Project A and Project B.

Project A

It's the main project and has settings. I have a check box to give user an option to "Repeat" track(s). This project can also access PROJECT B's public instances.

Project B

It's the BackgroundAudioAgent and has it's own settings. This project doesn't have access to PROJECT A settings. Therefore, in PROJECT A , I need to access the settings of PROJECT B and save it there. So that, when the "Repeat" is enabled, the agent restarts playing.

PROBLEM

I am unable to save the settings (in other words, the settings are saved, but it does not take any affect) when the BackgroundAudioPlayer's instance is running. I always have to close the instance, and when I do that, the settings can be changed.

QUESTION

  1. What is the most efficient way to do what I am trying to do?

  2. How can I save the settings in the IsolatedStorage without closing the BackgroundAudioPlayer's instance? (as I don't want to interrupt any track being played).

CODE: What I have to do to save settings.

    public bool SettingAudioRepeat
    {
        get
        {
            return GetValueOrDefault<bool>(SettingAudioRepeatKeyName, SettingAudioRepeatDefault);
        }
        set
        {
            if (AddOrUpdateValue(SettingAudioRepeatKeyName, value))
            {
                bool resumePlay = false;

                try
                {
                    if (BackgroundAudioPlayer.Instance.PlayerState != PlayState.Shutdown)
                    {

                        BackgroundAudioPlayer.Instance.Close();
                        resumePlay = true;
                    }
                }
                catch { }
                TaskEx.Delay(300);
                IQR_Settings iqrSet = new IQR_Settings();
                iqrSet.SettingAudioRepeat = value;
                iqrSet.Save(); //Saving the settings for Project B

                Save(); //Saving the settings for Project A

                try
                {
                    if (resumePlay)
                        BackgroundAudioPlayer.Instance.Play(); //It starts all from scracth

                }
                catch { }

            }
        }


    public T GetValueOrDefault<T>(string Key, T defaultValue)
    {

        T value;

        // If the key exists, retrieve the value.
        if (settings.Contains(Key))
        {
            value = (T)settings[Key];
        }
        // Otherwise, use the default value.
        else
        {
            value = defaultValue;
        }
        return value;
    }

CODE: What I simply want to do.

    public bool SettingAudioRepeat
    {
        get
        {
            return GetValueOrDefault<bool>(SettingAudioRepeatKeyName, SettingAudioRepeatDefault);
        }
        set
        {
            if (AddOrUpdateValue(SettingAudioRepeatKeyName, value))
            {

                IQR_Settings iqrSet = new IQR_Settings();
                iqrSet.SettingAudioRepeat = value;
                iqrSet.Save(); //Saving the settings for Project B

                Save(); //Saving the settings for Project A


            }
        }

回答1:

I agree that Background Audio is a breast. Whenever using any background agent you cannot rely on the ApplicationSettings to be synced. If you want to have settings saved and accessed from the UI (app) and background (audio agent) you should save a file. You can serialize the settings using Json.Net and save a file to a known location. Here is sample of what is might look like

// From background agent
var settings = Settings.Load();
if(settings.Foo)
{
    // do something
}

And here is a sample Settings File. The settings would need to be saved on a regular basis.

public class Settings
{
    private const string FileName = "shared/settings.json";

    private Settings() { }

    public bool Foo { get; set; }

    public int Bar { get; set; }

    public static Settings Load()
    {
        var storage = IsolatedStorageFile.GetUserStoreForApplication();
        if (storage.FileExists(FileName) == false) return new Settings();

        using (var stream = storage.OpenFile(FileName, FileMode.Open, FileAccess.Read))
        {
            using (var reader = new StreamReader(stream))
            {
                string json = reader.ReadToEnd();
                if (string.IsNullOrEmpty(json) == false)
                {
                    return JsonConvert.DeserializeObject<Settings>(json);
                }
            }
        }
        return new Settings();
    }

    public void Save()
    {
        var storage = IsolatedStorageFile.GetUserStoreForApplication();
        if(storage.FileExists(FileName)) storage.DeleteFile(FileName);
        using (var fileStream = storage.CreateFile(FileName))
        {
            //Write the data
            using (var isoFileWriter = new StreamWriter(fileStream))
            {
                var json = JsonConvert.SerializeObject(this);
                isoFileWriter.WriteLine(json);
            }
        }
    }
}

I personally have a FileStorage class that I use for saving/loading data. I use it everywhere. Here it is (and it does use the Mutex to prevent access to the file from both background agent and app). You can find the FileStorage class here.