eikuh
eikuh

Reputation: 697

async/await bad practice under Android?

Currently I am porting an existing C# Windows 8 / iOS app to Android (with Xamarin).

I used a lot of async/await for file IO, dialogs, network, etc…

What happens when the app is paused/suspended during an await call? Under Windows and iOS there are two possibilities:

In both cases, there is no memoy leak, there are no changes in control flow.

However, under Android, an Activity can be destroyed and recreated while the process stays alive. In my understanding of async/await this means:

Are my assumtions true? If yes, what can be done? (without making the program as complicated as before of the invention of async/await)

Upvotes: 6

Views: 3440

Answers (2)

Dave
Dave

Reputation: 2308

An Android Activity is guaranteed to call OnPause before the activity is deactivated/destroyed and OnResume when it starts up (see http://developer.android.com/training/basics/activity-lifecycle/index.html).

How about if you had a CancellationTokenSource available from your Activity. Then in OnPause you can call Cancel and then use:

try
{
    // Your async code
    ...
}
catch (OperationCancelledException e)
{
}

See also http://msdn.microsoft.com/en-us/library/jj155759.aspx for cancelling async tasks.

More a suggestion than a definitive answer, but I hope it helps.

Edit:

When I started introducing async/await into my code I found it to be like a zombie virus. Once you start asyncing you find it spreads throughout the rest of your code. It may be that you've got lots of async calls for the same reason. There are generally two rules to follow:

  1. Declare methods as public async Task Foo() instead of public async void Foo()
  2. Don't block on async code

In my own practice, I've discovered 2 places where you can break these general rules.

  1. If you're at the 'top' (i.e. the UI) of your code, there may be places where you have to declare code as async void because the delegate you're overriding takes void as a return type. A typical example of this is with a button.Click method.
  2. I had a database call which looked up a single value in a database. If I converted that to async, lots of my code elsewhere would have to change. I discovered that if you're guaranteed, and I mean guaranteed, to be at the 'bottom' of your code, specifically that none of the methods below the one you're calling use async, then you can safely call .Result on a Task. This saved me from asyncing half my code unnecessarily.

Hope this helps.

Upvotes: 1

Tom Opgenorth
Tom Opgenorth

Reputation: 1511

You could use a service to perform these long running tasks. Another option would be to use a headless fragment (one without a view and that it's .RetainInstance property set to true).

Upvotes: 0

Related Questions