Warnygo, please vote !

Discover Warnygo ! An amazing geolocation application allowing you to know everything that’s happening around you! From now on, you will never miss what’s inevitable again!


You saw the police putting fines in the neighborhood? Warn people around you by sending a Warny on the network! Your favorite star is in town, but you didn’t know he/she was coming? You’re lucky, a Warny was just sent to inform you! Imagine now, the countless possibilities such a service could offer...........


In a few days, Microsoft Windows Phone 7 will be released. On this occasion, Microsoft is organizing a development contest for programmers eager to get an aid for their project. Warnygo is one of those projects: I’m counting on you for it to catch the jury’s attention!

All you have to do is to follow this link: http://www.facebook.com/video/video.php?v=465703466010 and to «Like» it in order for the application to get a maximum of votes. Of course, I’m inviting you to forward this link so that it will reach as many people as possible.


Here are the detailed instructions:

[WP7] Do you need to cache data ?

ASP.NET developers  implement caching data frequently to avoid requesting  the database each time. It is always useful to think that your mobile users don’t have a super 3G/WIFI connection every time.

If as in ASP.NET, you want to add an expiration, meaning that the object is available for a certain period, you must pass by specific code, it’s not possible with standard API.

To achieve this functionality, you must develop a wrapper, so let’s take a look on the code:

The first step is to create a class named cache that contains a singleton, it also contains values for NoAbsoluteExpiration and NoSlidingExpiration.

    public sealed class Cache
    {
        public static readonly DateTime NoAbsoluteExpiration = DateTime.MaxValue;
        public static readonly TimeSpan NoSlidingExpiration = TimeSpan.Zero;

// Acces to the isolatedstorage
        readonly IsolatedStorageFile _myStore = IsolatedStorageFile.GetUserStoreForApplication();

// singleton
        private static Cache _current;
        public static Cache Current
        {
            get { return _current ?? (_current = new Cache()); }
        }

Like the ASP.NET API, we write a method to add an item to the cache and to set the timeouts.

An object in the cache is defined by a key (to return it), the object that will be serialized and the timespan/datetime parameters.

/// <summary>
/// Adds the specified key.
/// </summary>
/// <param name="key">The key.</param>
/// <param name="value">The value.</param>
/// <param name="absoluteExpiration">The absolute expiration.</param>
/// <param name="slidingExpiration">The sliding expiration.</param>
public void Add(string key, object value, DateTime absoluteExpiration, TimeSpan slidingExpiration)
{
    lock (_sync)
    {
        if (Contains(key))
            Remove(key);

        if (absoluteExpiration == NoAbsoluteExpiration)
            Add(key, DateTime.UtcNow + slidingExpiration, value);
        if (slidingExpiration == NoSlidingExpiration)
            Add(key, absoluteExpiration, value);
    }
}

Then we add the object in the isolated storage. For each key, a directory with the key as name is created, then we create a file named with the expiration date with the Windows file time UTC format (A Windows file time is a 64-bit value that represents the number of intervals of 100 nanoseconds that have elapsed since 12: 00 midnight, 1 January 1601).

/// <summary>
/// Adds the specified key.
/// </summary>
/// <param name="key">The key.</param>
/// <param name="expirationDate">The expiration date.</param>
/// <param name="value">The value.</param>
private void Add(string key, DateTime expirationDate, object value)
{
    lock (_sync)
    {
        if (!_myStore.DirectoryExists(key))
            _myStore.CreateDirectory(key);
        else
        {
    // If the key exist, we delete the directory and the file
            string currentFile = _myStore.GetFileNames(string.Format("{0}\\*.cache", key).FirstOrDefault();
            if (currentFile != null)
                _myStore.DeleteFile(string.Format("{0}\\{1}", key, currentFile));
            _myStore.DeleteDirectory(key);
            _myStore.CreateDirectory(key);
        }

        string fileName = string.Format("{0}\\{1}.cache", key, expirationDate.ToFileTimeUtc());


        if (_myStore.FileExists(fileName))
            _myStore.DeleteFile(fileName);

      using (var isolatedStorageFileStream = new IsolatedStorageFileStream(fileName, FileMode.OpenOrCreate, _myStore))
         {
           DataContractSerializer s = new DataContractSerializer(value.GetType());
           s.WriteObject(isolatedStorageFileStream, value);
         }
    }
}

Then the last step is to retrieve the value in the cache, if the cache has expired, the method returns null.

/// <summary>
/// Gets the specified key.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key">The key.</param>
/// <returns></returns>
public T Get<T>(string key)
{
    lock (_sync)
    {
// Getting th file
        string currentFile =  _myStore.GetFileNames(string.Format("{0}\\*.cache", key).FirstOrDefault();
        if (currentFile != null)
        {
// We check if the cache has not expired
            var expirationDate =
                DateTime.FromFileTimeUtc(long.Parse(Path.GetFileNameWithoutExtension(currentFile)));
            if (expirationDate >= DateTime.UtcNow)
            {
// read the file from the isolatedstorage
                using (var isolatedStorageFileStream = new IsolatedStorageFileStream(
string.Format(@"{0}\{1}", key, currentFile), FileMode.Open, _myStore))
                {
                    DataContractSerializer s = new DataContractSerializer(typeof(T));
                    var value = s.ReadObject(isolatedStorageFileStream);
                    isolatedStorageFileStream.Close();
                    return (T)value;
                }
            }
// If the cache has expired, we delete the file from the isolatedstorage
            Remove(key);
        }
        return default(T);
    }
}

Now that we have the foundations for a cache system,  we can use it easily with a bit of Rx. In this example, we have a GetAll method that returns data from a WCF service. The MyServiceClient was generated by Visual Studio.

public void GetAll(Action<ObservableCollection<MyEntity>> callback)
{
    // We check if the cache has not expired
    if (Cache.Current.Contains("KEY1"))
    {
        // W read the cache in a new thread then we call the callback in the dispatcher thread
        Observable.Start(() =>
                            Cache.Current.Get<ObservableCollection<MyEntity>>("KEY1"), Scheduler.ThreadPool).
            ObserveOn(Scheduler.Dispatcher).Subscribe(callback);
        return;
    }
    // New WCF client
    MyServiceClient client = new MyServiceClient();
    Observable.FromEvent<GetAllCompletedEventArgs>(client, "GetAllCompleted")
            .ObserveOn(Scheduler.ThreadPool)
            .Select(s =>
            {
                // In a new thread, we had the object received by WCF in the cache,
                    //the life time is 1 day
                if (s.EventArgs.Error == null)
                {
                    Cache.Current.Add("KEY1", s.EventArgs.Result, Cache.NoAbsoluteExpiration, TimeSpan.FromDays(1));
                }
                return s;
            })
        .ObserveOn(Scheduler.Dispatcher).Subscribe(s =>
        {
            // Then in the dispacher thread, we call the callback
            callback(s.EventArgs.Result);
        });
    // Async call for the GetAll method
    client.GetAllAsync();
}

This code is used for the Warnygo project, and is of course available in full: Phone7.Fx.Preview.zip

If you have feedback, you are welcome !

Hi there !

 

Specialized in .net technologies for many years, I am a technology fan in both asp.net and wpf/silverlight, using c# and .net 4.5

Taking advantages of new opportunities offered by the Windows Azure platform and WP/Win 8, I develop applications for Windows Phone, 5 of them are already available on the market place.


 

 

Month List