How to Build Your App With Lightning Fast Speed Using Akavache Caching

Akavache is an asynchronous, persistent (i.e. writes to disk) key-value store created for writing desktop and mobile applications in C#, based on SQLite3. Akavache is great for both storing important data (i.e. user settings) as well as cached local data that expires.

Downloading and storing remote data from the internet while still keeping the UI responsive is a task that nearly every modern application needs to do.

However, many applications that don’t take the consideration of caching into the design from the start often end up with inconsistent, duplicated code for caching different types of objects.

Getting Started with Akavache

Interacting with Akavache is primarily done through an object called BlobCache. At App startup, you must first set your app’s name via BlobCache.ApplicationName – on the desktop, your application’s data will be stored in %AppData%\[ApplicationName] and %LocalAppData%\[ApplicationName].

Store data that should be shared between different machines inBlobCache.UserAccount and store data that is throwaway or per-machine (such as images) in BlobCache.LocalMachine.

I have my Akavache caching on a PCL business library, where should be the core logic. Just let the view invoke helpers interacting with caching.

That way we don’t have chances to expose our application to multiple dependencies or possible circular references. All I have to do on my PCL library class was to open App.cs file, include “Akavache” namespace and add one line on the Initialize().

public override void Initialize()
{        
  BlobCache.ApplicationName = "Myapp";
}

Once it is set, I can start invoking BlobCache in all my View controllers logic and leverage the power of this caching mechanism. Akavache provides multiple helpers to save and get custom classes objects and those helpers will come handy depending what you are targeting. However, after few months of use I have my favorite one which handles all my situations on a very gracefully matter.

 

Below logic can be used with InMemory or LocalMachine options and what I like the most is it will try to retrieve from Caching or invoking our method to fill the space.

If both fail to fill the request or return an invalid object, the result would be null which we can check later on. Other helpers of Akavache to get an object for a given key will throw and exception if the key is invalid, therefore, if using such alternative we would need to wrap our code into try/catch mentality.

public async Task MyTask()
{        
  var result = BlobCache.LocalMachine.GetOrFetchObject("CacheKey" () => method.MyMethod(), DateTimeOffset.Now.AddHours(XXX));
}

Above line will execute a request to Akavache and continue the sequence of code without waiting for the response to come back. If we need to have the result in order to continue, the alternative here is to place the await command in front of BlobCache.

It took me almost one hour to realize that I needed to include Reactive library to get it working. So, I’m sharing with you the tips on what code to use:

using System.Reactive.Linq;   // IMPORTANT - this makes await work!

public async Task MyTask()
{        
  var result = await BlobCache.LocalMachine.GetOrFetchObject("CacheKey" () => method.MyMethod(), DateTimeOffset.Now.AddHours(XXX));
}

Akavache is very powerful and extensive that I might get a second article to go more in advanced mode to demonstrate the true potential of caching with this library if used correctly. Times would come where we would want to perform some Init() logic to warm up caching and place an object in memory to be later used.

This is perfect for View controller initialization like images or data (oh yea Akavache has a helper to cache images). The trick here is to use the “Subscribe” approach like the following code.

// Akavache Image helper

BlobCache.LocalMachine.LoadImageFromUrl(myurl).Subscribe(image =>
{
  myimg = image;
															
  // fresh image IBitmap type, let's do something on the UI screen maybe??						
});

// Data Subscribe for Later use
BlobCache.LocalMachine.GetOrFetchObject ("mykey", () => my_method.Method(), DateTimeOffset.Now.AddMinutes (XX)).Subscribe (results => {
var example = results;
// I have on "example" the valid results
});

// I finish processing, invalidate key and remove element from caching
BlobCache.InMemory.Invalidate(mykey);

Conclusion

Just by using these recommendations you will be able to build an app that is fully responsive, reliable and capable of handling scalability as your audience grow.

It is key that your app is being built with appropriate architecture, leveraging caching correctly and aiming for high-quality output.

Leave a Reply