C# - 执行200个http get请求并输出结果

标签 c# http asynchronous parallel-processing console-application

我有一个控制台应用程序,用户可以在其中输入菜单选项 (1-5),我执行一些功能并输出结果。

其中一个功能是对某个 url 执行 200 个 http get 请求,获取所有结果,对它们进行一些处理并输出给用户。

这是我当前的代码:

        Parallel.For(0, 200, i =>
        {
            String[] words = webApi.getSplittedClassName();
            for (int j = 0; j < words.Length; j++)
            {
                wordsList.Add(words[j]);
            }

        });

getSplittedClassName:

    public string[] getSplittedClassName()
    {
        HttpResponseMessage response = null;
        try
        {
            response = httpClient.GetAsync(url).Result;
        }
        catch (WebException e)
        {
            return null;
        }
        return parser.breakdownClassName(response);
    }

现在,由于用户输入了一个选项编号,程序执行了所需的功能,然后我输入了输出,我认为异步执行 http 工作没有意义,所以它都是同步的。

问题是处理请求需要很多时间,大约 30-40 秒..这有意义吗?

基本上有3个特征:做1个请求,做3个请求和200个请求。

执行 200 个请求并等待所有结果的最佳选择是什么?是不是应该像只发一个请求一样同步?

谢谢

最佳答案

Parallel.For()倾向于假设您的操作主要受 CPU 限制,因此它将使用一定程度的并行性,该并行性已根据您的机器拥有的 CPU 内核数进行了调整。但是 HTTP 请求往往是 IO 绑定(bind)的,所以你的大部分时间都花在等待目标机器将信息发回给你。

这意味着这是使用异步处理的好机会。尝试这样的事情:

public async Task<string[]> getSplittedClassName()
{
    HttpResponseMessage response = await httpClient.GetAsync(url);
    return parser.breakdownClassName(response);
}

还有这个:

    var classNameTasks = Enumerable.Range(1, 200)
        .Select(i => webApi.getSplittedClassName())
        .ToArray();
    wordList.AddRange(
        Task.WhenAll(classNameTasks).Result
            .SelectMany(g => g));

解释:

  1. 制作getSplittedClassName() async 这样它就不会同步获取所需的内容然后返回结果,而是立即返回 Task<>。将在结果可用时完成。
  2. 我删除了吃掉所有异常的代码,因为这通常是一种不好的做法。如果这里出现异常,您应该考虑您真正想要做什么:您是否应该重试该请求?只是让异常被抛出?忽略此类问题通常不是一个好主意。
  3. Task.WhenAll()将返回 Task<>这将返回给定任务的所有结果。您可以同步等待所有这些任务完成,然后将它们全部添加到 wordList作为一批。这是线程安全的,因为所有项目都添加到 wordList在单个线程上,而您的原始代码有多个线程可能会尝试将值添加到 wordList同时。

此外,我假设这只是一个家庭作业,但如果这是一个真实场景,那么您同时对同一个 URL 执行 200 个 GET 请求的事实将是一个大危险信号.

关于C# - 执行200个http get请求并输出结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36941563/

相关文章:

c# - CreateMap 抛出异常

c# - 如何让这个 CLR 与 2005 一起工作?

c# - 在 .Net 中使用哪种货币舍入算法?

internet-explorer - 在 Internet Explorer 中使用同步可插入协议(protocol)的自定义 url 协议(protocol)的最大长度是多少?

只返回我想要的某些元素的Java Http请求

http - ECS不会启动实例, "unable to place a task because the resources could not be found."

c# - 使用 TPL 并行运行任务

C# async await Task.delay 实战

c# - 如何调用具有某种优先级的异步方法?

c# - 在其他函数中控制动态创建的列表框属性