Get an error when creating the IsolatedStorageCache when app is run for the 2nd time

Apr 27, 2011 at 4:24 AM
Edited Apr 27, 2011 at 4:26 AM

I'm trying to use the IsolatedStorageCache. I register in unity as follows

 var isolatedStorageCacheManager = new IsolatedStorageCache("AdvancedSearchCache", 5120, 50, 10, TimeSpan.FromSeconds(5));
            unityContainer.RegisterInstance<ObjectCache>(isolatedStorageCacheManager);

Works fine the first time the application runs. It stores the objects in cache and I'm able to retrieve it. Now if I close the app and run it again I straight away get this error

System.ArgumentNullException occurred
  Message=Value cannot be null.
Parameter name: type
  StackTrace:
       at System.Runtime.Serialization.Json.DataContractJsonSerializer.Initialize(Type type, IEnumerable`1 knownTypes)
       at System.Runtime.Serialization.Json.DataContractJsonSerializer..ctor(Type type, IEnumerable`1 knownTypes)
       at Microsoft.Practices.EnterpriseLibrary.Caching.SerializationUtility.ToObject(Byte[] serializedObject)
  InnerException:

in the SerializationUtility.Silverlight.cs in the ToObject method. Not sure what this means. The error is in the line in bold below. But if I hit F5 it continues and it doesnt load anything from cache. If I clear the application storage and start the app then it works fine again. Is this a bug or am I doing something wrong here?

// creating a new offset stream as DataContractJsonSerializer.ReadObject(Stream) always sets stream.Position = 0L
            using (var inMemoryData = new MemoryStream(serializedObject, position, serializedObject.Length - position))
            {
                var serializer = new DataContractJsonSerializer(valueType, knownTypes);
                return serializer.ReadObject(inMemoryData);
            }
Note :: I'm using the silverlight dll's here and my application is Prism 4 based and I'm creating teh IsolatedStorageCache in the Bootstrapper.
Apr 27, 2011 at 9:51 AM

Hi,

My apologies but I'm not familiar with the IsolatedStorageCache class. Is this a user defined class? I'm not really sure but looking at your code, it seems it doesn't relate to Enterprise Library. Have you used caching block from Enterprise Library? Looking at the behavior, I guess you are using a null backing store here.

 

Noel Angelo Bolasoc
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com

Apr 27, 2011 at 9:54 AM

Yes. I'm using the Enterprise Library. I downloaded the source (version 5.0.414.0) and built the silverlight projects and using the dll's. I have followed the steps as shown in this video.

http://channel9.msdn.com/posts/Enterprise-Library-for-Silverlight-Data-Caching-demo

It gives me this error if I dont clear the app storage before running the app the second time.

Apr 27, 2011 at 11:20 AM

We are currently looking in to this. We'll get back to you soon for any updates.

 

Noel Angelo Bolasoc
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com

Apr 27, 2011 at 12:49 PM

Thanks Noel.

Apr 28, 2011 at 11:46 AM

Hi gan,

Can you send us a small repro project of this? I'm not sure but I think you are caching it in memory.

 

Noel Angelo Bolasoc
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com

Apr 28, 2011 at 12:06 PM

I'll send one soon. But I'm sure i;m not using in memory caching.

Apr 28, 2011 at 12:47 PM

Looks like it has been fixed. It fails against the cod base version 86778 but works fine with 87489.

Apr 29, 2011 at 3:16 AM

Thanks for sharing this out :).

 

Noel Angelo Bolasoc
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com

Apr 29, 2011 at 7:03 AM

Actually Noel I'm able to reproduce the issue with 87489 as well and now I know why it is the case. Here is the app demonstrating the issue.

Steps to reproduce

  • Run the app
  • First time cache is empty all works fine
  • Main page is loaded, which asycnhronously downloads a prism module and loads into MainRegion
  • Select something from the combo and click on "Save to cache"
  • Click on "Load from cache" and it works fine.
  • If you go to the isolated storage on the m/c and open the file you will see the json is saved with this type name "ModuleA.MyObject, ModuleA, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
  • Now hit browser refresh
  • Now when the IsolatedStorageCache is getting instantiated in the Bootstrapper it will complain because
    • It sees something is there in the cache and decides to deserialise it and calls the ToObject method in the SerializationUtility.Silverlight.cs
    • Here it gets this type "ModuleA.MyObject, ModuleA, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" into the splitTypeNames variable.
    • Now it tries to do Type.GetType(splitTypeNames[0]) and fails

The reason is that type is in ModuleA which has not yet been downloaded. This scenario needs to be handled as this is a very generic scenario. You cannot expect all types to be available when a sl app starts as sl is asynchronous. And with Prism, where modules can be downloaded OnDemand, this kind of logic will definitely fail. This needs to be fixed else it cannot be used with prism based apps (loosely coupled apps).

Cheers,

Ganesh

Apr 29, 2011 at 8:16 AM
Edited Apr 29, 2011 at 8:23 AM

Thanks for this valuable information! I can't seem to download the file from the link you provided. Anyways, if you are really sure that this is an issue, just feel free to log this on our issue tracker found here. Specify there how did you reproduced the issue and also include your repro project.

 

Noel Angelo Bolasoc
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com

Apr 29, 2011 at 8:57 AM

Try this link. It is important you run the app and see the issue for yourself.

Thanks.

May 3, 2011 at 4:48 PM
Edited May 3, 2011 at 4:49 PM

Please let me know if you were able to download the project and reproduce the issue.

Have also logged in the issue tracker for this.

http://entlib.codeplex.com/workitem/30618

Thanks.

May 4, 2011 at 12:08 AM

@gan_s

The behavior you descirbed is the way the Caching block for Silverlight is designed. I've asked one of our developers to post a workaround to avoid the situation by making everything in the cache loaded by the time the cache is deserialized, which, by the way, might not be feasible in all scenarios.

Regards,

Grigori,
Enterprise Library Producer

May 4, 2011 at 12:26 AM

Hi Ganesh,

As Grigori mentioned, this is how the Caching block was designed. A workaround is to avoid this issue entirely by only caching objects whose types are available at application initialization time. In this particular case -using Prism async module loading feature- means that both the lazy loaded module and the main application should have a reference to a common assembly (a contract), that has the POCO object that you want to add to the cache. This is so that when the application starts, even if the lazy loaded module is not yet available, that particular type is.

It may not be an ideal workaround in some scenarios, but having shared assemblies between modules & the main application is a typical approach used for communicating the different application pieces.

Anyways, this improvement will definitely be considered for the next version of the Enterprise Library Silverlight Integration Pack, so thanks for submitting the bug so other users can vote for it.

 

Thanks,
Julian Dominguez 

May 4, 2011 at 4:45 AM

Hi Julian,

The proporse workaround would not be applicable for all scenarios as you have mentioned. Certain types need not be shared in a applications scope. We need to be able to handle these scenarios as well rather than modifying an existing application to make use of the caching block.

I can wait till the fix is out.

Thanks.

May 4, 2011 at 7:13 PM

Just to set your expectations, there's currently no plans to change the behavior of the Caching block for this release (we are shipping next week!)

 

May 5, 2011 at 3:50 AM

No issues. Take your own time. I have an alternative solution at my end to help me do this. Also I feel that you should be deserialising only when we try to retrieve from the cache and not when the isolatedstoragecache is instantiated.

Jul 12, 2011 at 7:25 AM

Has any action been taken on this yet?

Jul 13, 2011 at 4:44 PM

The behavior did not change in the release as Grigori mentioned, and the Enterprise Library team is not currently working on the Silverlight integration pack, as it is now focused in the Azure integration pack (read Grigori's post here).

Sorry if this is preventing you from using the block as is, but I encourage you to extend the code or update it to fit your needs, as the license is very permissive.