Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Size for ApplicationDataCompositeValue

I'm porting my published app in Windows Phone, to Win 8. While trying to write to the IsolatedStorage equivalent, ApplicationDataContainer, I get an exception. The exception says

Error : The size of the state manager setting has exceeded the limit

I'm not sure if this is the correct way of using the ApplicationDataContainer.

public void WriteToIsolatedStorage()
    {
        try
        {

            ApplicationDataContainer localSettings = ApplicationData.Current.LocalSettings;
            ApplicationDataCompositeValue composite = new ApplicationDataCompositeValue();

            if (localSettings.Containers.ContainsKey("LoveCycleSetting"))
            {
                localSettings.DeleteContainer("LoveCycleSetting");
            }

            composite["GetWeekStart"] = m_bWeekStart;

            composite["iHistCount"] = m_iHistCount;

            composite["dtHistory"] = this.DateTimeToString(m_dtHistory);

            composite["avgCycleTime"] = m_iAvgCycleTime;
       }
    }

The exception occurs at the second last line. m_dtHistory is a string array of size 400. So does the ApplicationDataCompositeValue have a fixed size? Or do I have to write the m_dtHistory array into a file? Cuz in WindowsPhone I could directly write the array into the IsolatedStorageSettings.

It would be really helpful if someone could guide me on this or give links.

Alfah

like image 975
alfah Avatar asked Jun 20 '12 07:06

alfah


2 Answers

Yes, ironically settings storage is easier on the phone than WinRT. You can just serialize to a file instead. Here is what I did (partially copied from the code already in SuspensionManager.cs), which works for both value and reference types.

    internal static async Task<bool> SaveSetting(string Key, Object value)
    {
        var ms = new MemoryStream();
        DataContractSerializer serializer = new DataContractSerializer(value.GetType());
        serializer.WriteObject(ms, value);
        await ms.FlushAsync();

        // Uncomment this to preview the contents being written
        /*char[] buffer = new char[ms.Length];
        ms.Seek(0, SeekOrigin.Begin);
        var sr = new StreamReader(ms);
        sr.Read(buffer, 0, (int)ms.Length);*/

        ms.Seek(0, SeekOrigin.Begin);
        StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync(Key, CreationCollisionOption.ReplaceExisting);
        using (Stream fileStream = await file.OpenStreamForWriteAsync())
        {
            await ms.CopyToAsync(fileStream);
            await fileStream.FlushAsync();
        }
        return true;
    }

    // Necessary to pass back both the result and status from an async function since you  can't pass by ref
    internal class ReadResults
    {
        public bool Success { get; set; }
        public Object Result { get; set; }
    }
    internal async static Task<ReadResults> ReadSetting<type>(string Key, Type t)
    {
        var rr = new ReadResults();

        try
        {
            var ms = new MemoryStream();
            DataContractSerializer serializer = new DataContractSerializer(t);

            StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync(Key);
            using (IInputStream inStream = await file.OpenSequentialReadAsync())
            {
                rr.Result = (type)serializer.ReadObject(inStream.AsStreamForRead());
            }
            rr.Success = true;  
        }
        catch (FileNotFoundException)
        {
            rr.Success = false;
        }
        return rr;
    }
like image 144
Ray Ackley Avatar answered Oct 16 '22 03:10

Ray Ackley


The name of each setting can be 255 characters in length at most. Each setting can be up to 8K bytes in size and each composite setting can be up to 64K bytes in size.

https://msdn.microsoft.com/library/windows/apps/windows.storage.applicationdata.localsettings.aspx

like image 33
Tealc Wu Avatar answered Oct 16 '22 03:10

Tealc Wu