#async task and the for loop bug

I have used various flavours of async task implementation.
* WP7 / async CTP / v3 VS 2010
* Win8 / VS 2012
* Azure / VS 2012
* SL / async targetting pack / VS 2012

I blogged about how i had issues with #async on #aszure and funnily enough i wasn’t the only one. As discussed in https://invokeit.wordpress.com/2012/11/07/windows-azure-and-async-task-mechanism-async/ if you use something like this

AsyncDataSourceObj aeo = new AsyncDataSourceObj();

protected async Task BuildFilmDataSet()
{
    Films films = await aeo.GetFilmData();
    foreach(var film in films)
    {
        Cinemas cinemas = await aeo.GetCinemaData(film);

        // do things

        // do more things 
    }
}

It doesn’t work and a little investigation showed me that i wasn’t doing anything wrong.

The moment await aeo.GetCinemaData(film); gets called, the execution instead of awaiting moves to the next iteration of for loop. Why in the world you would want that ? I am sure if you wanted that one would have used Parallel.For instead.

For some reason, the creators thought that we clever people wouldn’t ever want to do a async call in for loop. I mean its not like its the most common loop usage etc…

The suggestion is to use Task.Yield() (or TaskEx.Yield) within for loop

It however doesn’t always work. I have tried it with my last Silverlight + Async Targetting pack and its still the same. Infact I had to revert to event based async in that case.

Here’s a screen of azure sample in action

Advertisements

11 thoughts on “#async task and the for loop bug

  1. I’ve played with this and can’t duplicate.
    I’ve tried
    for (int x =0; x,10;x++)
    {
    await Task.Delay(x*1000);
    Debug.WriteLine(string.Format(“Waited {0} seconds.”));
    }

    and
    var v = new int[] {0, 1, 2, … 9};
    foreach (var x in v)
    {
    await Task.Delay(x*1000);
    Debug.WriteLine(string.Format(“Waited {0} seconds.”));
    }

    but both waited for the time, instead of a new value being output once a second as you suggest above.

    • Oh i do.. except its happened both times I have tried this. This blog is about what I am doing. This problem is however not just restricted to me. I have seen a few posts relating to this issue.

    • also in both cases I was make external calls, in one case I was make http json WS calls, in other I was making SL RIA WCF call. In both cases the same behaviour is exhibited. We already know that .NET handles async event based code in the background and that along with async task pattern seems to be causing this issue.

  2. What I meant was, if you insert my code into yours, and try it, does it behave the same way. In that case it’s the compiler, as my vs2012 generates it correctly for a windows store app. If my code works as expected in your environment, it’s something else. I’m betting it’s the async targetting pack you’re using being a beta, personally, and not getting this bit right.

  3. I know this is an old post. But I would like to thank Hermit Dave for his original post. I was having a hell of a time trying to figure out why a phone app I am developing kept either freezing or exiting without notice. I have await GetDrivingRouteAsync in a foreach loop. As soon as I changed it to a traditional for loop, e.g. for (i=0; i < some count; ++i) everything worked fine. My notion is the async/await sets up a condition that periodically stomps on the foreach iterator. OF course, this is mere speculation. But, there definitely is a difference, i.e. one works great and the other fails miserably…

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s