tl;dr: This article is the second of a series talking about the implementation of an async user Settings Service, using the C# async keyword. This part talks about writing new settings values, asynchronously and the challenges associated with it.

In this continuing implementation of a Settings Service series, I'll continue with the addition new features to the service.

This is a pretty simple code, and you'll notice that it uses async void, which should be avoided most of the time. But in this case, since the property is synchronous, using an async Task is not very useful, and produces a compiler warning.

The warning removal is actually not an excuse, but the environment leads us to write that kind of code, because of the mix of synchronous and asynchronous code.

Cancellation Management

Again here, cancellation needs to be added using an explicit cancellation token, passed-in as a parameter which is not represented in the previous example.

This implementation is using the cancellation token provided by the CancellationTokenSource that can be disposed at any time. This will work properly if the view model is disposed before the end of an async operation.

But what happens if a write operation takes way too much time to complete ? Do we keep stacking up these async calls ?

This could happen if the settings service is actually sending data off to a remote server, and the server is not responding properly. Another solution would be to create a cancellation token for each call make to Write, and cancel it if there's a new one made before the other ends.

By creating a disposable field that gets disposed when entering the StoreValue, it's now possible to cancel an outstanding Write operation.

Unfortunately, this code only guaranteed to work if it is running on the UI Thread, because there's only one UI Thread and that processing is serialized. By default, if nothing in particular is done since the property will mostly be assigned by the data-binding engine, everything will run on the Dispatcher.

But if for some reason, the code ends up running on a different thread, the problem here is that the _outstandingWrite private field is now a parallelism liability that could be modified by multiple threads at the same time. We can't put a lock here to protect it though, because it not permitted in an async method.

The throttle logic is integrated directly into the ViewModel, which is a lot of plumbing to repeat if there are multiple settings. Of course, this can be refactored and placed into a utility class, but there’s still going to be a need for state to be explicitly maintained to perform the throttle.

I've excluded the cancellation logic from this sample, but it'd eventually need to be added here.

This can also be used to persist the data to the storage, using the IsolatedStorageSettings.Save() method, but only write when enough time has passed by.

Next...

Writing to the settings service is actually not as easy as it seems, as there can be multiple concurrency scenarios to deal with.

In the next article, we'll talk about notifying code that the settings have changed which could be used to alter the behavior of the application when, let's say, the temperature unit has changed.

Cloud

About me

My name is Jerome Laban, I am a Software Architect, C# MVP and .NET enthustiast from Montréal, QC. You will find my blog on this site, where I'm adding my thoughts on current events, or the things I'm working on, such as the Remote Control for Windows Phone.