silverlight cache NameValueList in IsolatedStorage

silverlight cache NameValueList in IsolatedStorage

Old forum URL: forums.lhotka.net/forums/t/6334.aspx


davido posted on Wednesday, February 04, 2009

Has anyone got any thoughts on where would be a good place to introduce some code to write out a NameValueList/check for it's existence in a CSLA business object? I'm not concerned with the cache going stale at the moment.

RockfordLhotka replied on Thursday, February 05, 2009

You can use the MobileFormatter to do this.

It has some of the same restrictions as the BinaryFormatter though - in that a radical change to the structure of the business object (the class, in terms of fields and properties) may mean you can't recover the data later.

But for short-term data storage, and with an object that isn't likely to change its name, type or structure often (like a name/value list), and for a cache that you could re-create anyway, this is not a bad option.

Look at the ObjectCloner class in the CSLA SL code to see how the MobileFormatter is invoked. In the middle of the clone process, there's a MemoryStream that contains a byte array of the object's serialized state.

If you put that byte array into a file in IS, you could later retrieve that byte array, put it into a MemoryStream and then deserialize the data into the object.

Just make sure you carefully trap exceptions in the deserialization process. If you get an exception, just re-retrieve the data from the server and no one is the wiser that the cache didn't work.

davido replied on Thursday, February 05, 2009

Excellent I'll give that go. Thanks

skagen00 replied on Thursday, February 05, 2009

Because this subject came up (IsolatedStorage) I wanted to ask a followup question.

In the case of caching a list I initially thought - well, this is what IsolatedStorage can handle, super. The slight downside is that in the unlikely scenario you have a robust enough business app where you use tons of IsolatedStorage for caching things (some might say there's a design issue in this case), you're limited to 10MB (right? and you're prompted after only 1MB? -- I think I remember those #s)

What of using a static values for caching? In my tests they seem to work just fine and may be a little more natural to get to than using Isolated Storage keys.

One thing I have not had the chance to test (I'm still relatively new to Silverlight) is whether or not static variables count against memory limits of IsolatedStorage / Silverlight. Perhaps this is a novice question, but well, I'm novice at Silverlight.

Any insight into this?

RockfordLhotka replied on Thursday, February 05, 2009

You are right about the limits on IS size.

 

The question is cache duration.

 

Using static fields for caching works great, and will last as long as the Silverlight app is running, but no longer.

 

Using IS will last across execution of the app. So the user can shut down, come back tomorrow or next week, and as long as your class hasn’t changed substantially in the meantime, the cache will reload from IS.

 

Rocky

davido replied on Tuesday, April 21, 2009

Thanks for the advice Rocky. I finally got back to this project and I have it working.

I found this thread useful http://forums.lhotka.net/forums/thread/31260.aspx

and this link was also useful http://www.eggheadcafe.com/tutorials/aspnet/d566463d-83bd-486a-8633-53aa54f405bf/silverlight-2-beta-2-doi.aspx

I had to create a module level variable to hold the client callback so I could call it in dp_FetchCompleted after I had serialised the data to disk. I think this is ok.

When the file exists in IsoStorage I invoke the client call back with null i.e. handler.Invoke(null, dp);

I don't think there is a way for me to provide something other than null here because it is a static. What are the implications of sending a null here?

 

[Serializable]

[MobileFactory("XXX.Business.BusinessClasses.ClassificationsFactory, XXX.Business", "FetchClassifications")]

public class ClassificationsLookup : NameValueListBase<int, string>

{

#if SILVERLIGHT

public ClassificationsLookup(){}

//to allow the client handler to be called back

//I have intercepted the call back to facilitate isoStorage

public static EventHandler<DataPortalResult<ClassificationsLookup>> _handler;

public static void GetClassifications(EventHandler<DataPortalResult<ClassificationsLookup>> handler)

{

ClassificationsLookup classifications;

if (IsolatedStorageFile.GetUserStoreForSite().FileExists("classifications.dat"))

{.......populate a byte[] called b

   classifications = (ClassificationsLookup)wrapper.DecompressAndDeserialize(b);

}

DataPortalResult<ClassificationsLookup> dp = new DataPortalResult<ClassificationsLookup>(classifications, null, null);

handler.Invoke(null, dp);

}

else

{

_handler = handler;

DataPortal<ClassificationsLookup> dp = new DataPortal<ClassificationsLookup>();

dp.FetchCompleted += new EventHandler<DataPortalResult<ClassificationsLookup>>(dp_FetchCompleted);

dp.BeginFetch();

}

}

static void dp_FetchCompleted(object sender, DataPortalResult<ClassificationsLookup> e)

{

var w = new Wrapper();

byte[] b = w.SerializeAndCompress(e.Object);

using (IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForSite())

{

using (var isoStream = new IsolatedStorageFileStream("classifications.dat", FileMode.Create, isoStore))

{

isoStream.Write(b, 0, b.Length);

}

}

_handler.Invoke(sender, e);

}

elizas replied on Friday, June 11, 2010

We can use Isolated Storage as a virtual file system to store data in a hidden folder on our machine in silverlight application. Silverlight application is allocated the storage of 1 MB per application but we can increase the amount of storage.
This is the function to get the data in the isolated storage
 
  Private Function LoadData(ByVal fileName As String) As String
        Dim data As String = String.Empty
        Dim isfstream As New IsolatedStorageFileStream(fileName, FileMode.Open, IsolateStorageFileObj)
        Dim sr As New StreamReader(isfstream)
        data = sr.ReadLine()
        Return data
  End Function

Copyright (c) Marimer LLC