Friday, February 1, 2013

Common approach to cancel different asynchronous operations

Common approach to cancel different asynchronous operations

I have somewhat non-trivial task and I'd appreciate to hear from you, how to solve it better. In a nutshell, this is about managing long-running tasks of different nature. While I'm doing this for Windows Phone, I feel like some general principles could be applied here, based on C# and .NET standard approaches.

My application is mainly built around different service classes, which handles data from the cloud, GPS, commercial transactions, authentication, etc. All the services are owned by our team. Services are used inside view models, but API in different services is currently of different fashion. Somewhere it's async/await, somewhere it's event-based (like in positioning, where I need to update geo coordinate constantly).

Now I've started to look into the issue of application activation/deactivation, and I would like to handle this in a common way in all my view models. One of the main thing is cancellation of current async operations when app is closing or when user navigates to another page. I want to put the code related to that into something like BaseViewModel, to avoid code duplication. However this means that I need to handle cancellation in all view models uniformly.

Here comes the challenge. For example, async/await stuff could be cancelled by CancellationToken. I could collect all the cancellation tokens in BaseViewModel, and use them all when needed. However, this will not work with event-based asynchrony. Of course one could delegate concrete cancellation operation to child view model, via virtual function call. But I want to move as much as possible code to the BaseViewModel.

So, is there a way to unify cancellation of Tasks and event-based asynchrony?

Answers & Comments...

Answer: 1

The event-based pattern is somewhat non-uniform, so I don't see that a completely clean solution will exist without writing some case-by-case code for each operation. Some options could be:

  • Wrap up your non-task based async operations in tasks to provide a uniform approach. Requires quite a bit of boring code (due to the non-uniformity of the EAP).

  • Wrap up both your task and event subscriptions in a simple cancellation delegate, and have your base class just know about these cancellation actions instead (maybe a bit more than just an action, but something relatively simple)

It seems to me that anyway you will need to write per-event code for cancellation, but with the use of a couple of helper methods for storing the info for the task and event based operations, it might be quite lightweight.

by : Nicholas Whttp://stackoverflow.com/users/513410

Answer: 2

Why wouldn't the CancellationToken(Source) infrastructure work for event-driven components? You can register a callback with the token that is called when cancellation occurs. In that callback you can unsubscribe from event sources. Speaking in general terms you can perform any action necessary to quiescence the system. It is just a matter of distributing the token to all components concerned with cancellation.

Actually, this is the "beauty" of the CancellationToken(Source) infrastructure. It is so simple yet so generally applicable.

by : usrhttp://stackoverflow.com/users/122718




No comments:

Post a Comment

Send us your comment related to the topic mentioned on the blog