进行多次休息api调用并使用c#组合结果

时间:2017-02-03 13:05:28

标签: c# multithreading asp.net-web-api2

以下是我需要帮助的情况。

  • 用户输入关键字并点击搜索

  • 我正在为多个API提供该关键字,以便使用httpclient请求获取结果。

  • 我根据不同API的搜索关键字获得回复。

但问题是我正在逐一向这些api拨打电话。我想做一些事情,一旦用户点击搜索,它会立即调用所有API然后合并结果。

WalmartModel model=new WalmartModel();

using (var client = new HttpClient())
{
    client.BaseAddress = new Uri("**URL 1**");
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    //GET Method  
    HttpResponseMessage response = await client.GetAsync("");
    if (response.IsSuccessStatusCode)
    {
        model = await response.Content.ReadAsAsync<WalmartModel>();
    }
    else
    {
        Console.WriteLine("Internal server Error");
    }                
}


using (var client = new HttpClient())
{
    client.BaseAddress = new Uri("**URL 2**");
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    //GET Method  
    HttpResponseMessage response = await client.GetAsync("");
    if (response.IsSuccessStatusCode)
    {
        model = await response.Content.ReadAsAsync<WalmartModel>();
    }
    else
    {
        Console.WriteLine("Internal server Error");
    }                
}

一旦我得到了结果,我将列表合并并将其归还给我,我认为这不是最佳实践。

我知道我可以使用多任务线程,但我没有实际的例子可以遵循。谁能建议最好的方法来处理这个问题?

1 个答案:

答案 0 :(得分:3)

您可以采取以下方法。

将对不同API的调用封装到返回公共模型的异步函数中。在这种情况下,一种在查询URL后将返回WalmartModel的常用方法。

public async Task<WalmartModel> GetModel(string url, HttpClient client) {
    //GET Method  
    using(var response = await client.GetAsync(url)) {
        if (response.IsSuccessStatusCode) {
            return await response.Content.ReadAsAsync<WalmartModel>();
        } else {
            Console.WriteLine("Internal server Error");
        }
    }         
    return null;       
}

使用Task.WhenAll 等待所有API搜索,并在完成后收集结果

//Using a single client to make the calls.
using(var client = new HttpClient()) {
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    //create the search tasks to be executed
    var tasks = new []{
        GetModel("**URL 1**", client),
        GetModel("**URL 2**", client),
        GetModel("**URL N**", client),
    };

    // Await the completion of all the running tasks. 
    var responses = await Task.WhenAll(tasks); // returns IEmumerable<WalmartModel>

    var results = responses.Where(r => r != null); //filter out any null values
}

Task.WhenAll返回单个任务,该任务在任务集合中的所有任务完成后结束。