fasttimes
fasttimes

Reputation: 71

How can I convert this method to work asynchrnously?

I have this method which takes a URL and calls a web-api and then converts into SomeType. The API will only return 100 results at a time, and so if there are more results to be returned it also returns the next index number to start call the API again to get the next set. Once it fails to return the next starting index, we have finished getting everything. The initial call to the api cannot use the &start parameter, which is why I use the q variable.

What should I do to convert this to an async method, and how can I call it and get the Total updates as they are reported and then final results when the method finishes? For the latter I suspect I will need to wire up some events before calling the method asynchronously.

public MyResultsObject GetStuff(string query)
{
    var Total = 0;
    var q = query;
    var keepGoing = false;
    var results = new MyResultsObject();
    do
    {
        var json = new WebClient().DownloadString(q);
        var root = JsonConvert.DeserializeObject<SomeType>(json);
        keepGoing = (root.IsMoreStuff != null);

        //process stuff
        results.SomeList.Add(root.SomeInfo);
        Total += root.Count;  //Would be nice to send Total back to caller 

        if (keepGoing) q = query + "&start=" + root.nextStart;
    } while (keepGoing);

    return results;
}

Upvotes: 0

Views: 69

Answers (1)

spender
spender

Reputation: 120460

Something like this? I would suggest reporting the total with some sort of progress event that could be dispatched from within the loop, or perhaps something as simple as a callback supplied in the parameter list:

public async Task<MyResultsObject> GetStuffAsync(string query, 
                                                 Action<int> totalCallback)
{
    var Total = 0;
    var q = query;
    var keepGoing = false;
    var results = new MyResultsObject();
    do
    {
        string json;
        using(var webClient=new WebClient())
        {
            json = await webClient.DownloadStringTaskAsync(q);
        }
        var root = JsonConvert.DeserializeObject<SomeType>(json);
        keepGoing = (root.IsMoreStuff != null);

        //process stuff
        results.SomeList.Add(root.SomeInfo);
        Total += root.Count;  //Would be nice to send Total back to caller 
        if(totalCallback!=null)
        {
           totalCallback(Total);
        }
        if (keepGoing) q = query + "&start=" + root.nextStart;
    } while (keepGoing);

    return results;
}

then your call could be:

var stuff = await GetStuffAsync("myQuery", total => {
    //handle the total
})

Upvotes: 2

Related Questions