凡调用API时使用的并发 [英] Where to use concurrency when calling an API

查看:140
本文介绍了凡调用API时使用的并发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我做一个网页API调用一些C#项目,事情是,我做他们的方法的循环中。通常有没有这么多,但即使我想带并行的优势。

Inside a c# project I'm making some calls to a web api, the thing is that I'm doing them within a loop in a method. Usually there are not so many but even though I was thinking of taking advantage of parallelism.

我试图到目前为止

public void DeployView(int itemId, string itemCode, int environmentTypeId)
{
    using (var client = new HttpClient())
    {
        client.BaseAddress = new Uri(ConfigurationManager.AppSettings["ApiUrl"]);
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        var agents = _agentRepository.GetAgentsByitemId(itemId);

        var tasks = agents.Select(async a =>
            {
                var viewPostRequest = new
                    {
                        AgentId = a.AgentId,
                        itemCode = itemCode,
                        EnvironmentId = environmentTypeId
                    };

                var response = await client.PostAsJsonAsync("api/postView", viewPostRequest);
            });

        Task.WhenAll(tasks);
    }
}

但不知道这是否是正确的路径,或者我应该尽量平行整个DeployView(即即使使用以前的HttpClient)

But wonder if that's the correct path, or should I try to parallel the whole DeployView (i.e. even before using the HttpClient)

现在,我看到它贴出来,我想我不能只删除这个变量响应为好,只是做的await没有它设置为任何变量

Now that I see it posted, I reckon I can't just remove the variable response as well, just do the await without setting it to any variable

感谢

推荐答案

什么你介绍的 并发,不是 并行 。更多的是<一个href=\"http://stackoverflow.com/questions/1050222/concurrency-vs-parallelism-what-is-the-difference\">here.

您的方向是好的,但也有一些细微的变化,我会做:

Your direction is good, though a few minor changes that I would make:

首先,你应该标记你的方法异步任务为你使用 Task.WhenAll ,返回一个awaitable,您将需要异步等待。接下来,你可以简单地从 PostAsJsonAsync 返回,而不是等待你里面选择每个呼叫的操作。这将节省开销一点点,因为它不会产生状态机的异步调用:

First, you should mark your method as async Task as you're using Task.WhenAll, which returns an awaitable, which you will need to asynchronously wait on. Next, You can simply return the operation from PostAsJsonAsync, instead of awaiting each call inside your Select. This will save a little bit of overhead as it won't generate the state-machine for the async call:

public async Task DeployViewAsync(int itemId, string itemCode, int environmentTypeId)
{
    using (var client = new HttpClient())
    {
        client.BaseAddress = new Uri(ConfigurationManager.AppSettings["ApiUrl"]);
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(
                   new MediaTypeWithQualityHeaderValue("application/json"));

        var agents = _agentRepository.GetAgentsByitemId(itemId);
        var agentTasks = agents.Select(a =>
        {
            var viewPostRequest = new
            {
                AgentId = a.AgentId,
                itemCode = itemCode,
                EnvironmentId = environmentTypeId
            };

            return client.PostAsJsonAsync("api/postView", viewPostRequest);
        });

        await Task.WhenAll(agentTasks);
    }
}

的HttpClient 能够使并发请求(参见@usr链接查看更多),因此,我没有看到一个理由每次创建拉姆达内一个新的实例。请注意,如果你消耗 DeployViewAsync 多次,也许你会想保留的HttpClient 围绕你而不是分配每一个时间,处理一次你不再需要它的服务。

HttpClient is able to make concurrent requests (see @usr link for more), thus I don't see a reason to create a new instance each time inside your lambda. Note that if you consume DeployViewAsync multiple times, perhaps you'll want to keep your HttpClient around instead of allocating one each time, and dispose it once you no longer need its services.

这篇关于凡调用API时使用的并发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆