如何将此方法转换为异步工作?

时间:2014-01-03 02:24:08

标签: c# async-await

我有这种方法,它接受一个URL并调用web-api,然后转换为 SomeType 。 API一次只返回100个结果,因此如果要返回更多结果,它还会返回下一个索引号,以便再次开始调用API以获取下一个结果。一旦它无法返回下一个起始索引,我们就完成了所有操作。对api的初始调用不能使用& start参数,这就是我使用 q 变量的原因。

我应该怎么做才能将其转换为异步方法,如何调用它并在报告时获取Total更新,然后在方法完成时获得最终结果?对于后者,我怀疑在异步调用方法之前我需要连接一些事件。

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;
}

1 个答案:

答案 0 :(得分:2)

这样的东西?我建议使用某种可以从循环内调度的进度事件报告总数,或者可能像参数列表中提供的回调一样简单:

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;
}

那么你的电话可能是:

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