使用C#进行多个REST API调用并合并结果

4
以下是需要翻译的内容:

这里是我需要帮助的场景。

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

  • 我使用httpclient请求将该关键字提供给多个API,以获取结果。

  • 根据搜索关键字,我从不同的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");
    }                
}

一旦我得到结果,我就会将列表合并并返回它(我认为这不是最佳实践)。
我知道我可以利用多任务线程,但我没有实际的示例可供参考。有人能建议处理此问题的最佳方法吗?

2
同时发出多个请求并合并结果。https://msdn.microsoft.com/zh-cn/library/hh696703(v=vs.110).aspx - JamesT
至少提供一些代码,展示你现在是如何做到的。 - Evk
1
所以,这篇文章完美地回答了你的问题。 - spender
@SachinTrivedi,将调用封装到异步函数中,并使用Task.WhenAll收集所有结果。 - Nkosi
@SachinTrivedi 您的代码有所不同。您正在等待每个调用依次完成,然后才开始下一个下载。该文章在任何等待完成之前启动了所有下载任务。 - spender
显示剩余2条评论
1个回答

11

以下是你可以采取的方法。

将对不同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会返回一个单一的任务,该任务在集合中所有的任务都已经完成时才会结束。


我一定会尝试并告诉你结果。感谢你发布这段代码。 - Sachin Trivedi
我正在调用不同的API,它们返回不同的JSON响应。如何将它们的JSON响应合并成一个格式?即我正在调用沃尔玛和百思买的API。 - Sachin Trivedi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接