Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#-执行200个http get请求并输出结果_C#_Http_Asynchronous_Parallel Processing_Console Application - Fatal编程技术网

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

C#-执行200个http get请求并输出结果,c#,http,asynchronous,parallel-processing,console-application,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 < wo

我有一个控制台应用程序,用户在其中输入一个菜单选项(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]);
            }

        });
现在,由于用户输入一个选项号,程序执行所需的功能,然后我将输出放入,我认为没有必要以异步方式进行http工作,所以它都是同步的

问题是执行请求需要很多时间,大约30-40秒。。这有意义吗

基本上有3个特性:Do1请求、Do3请求和200请求

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

感谢并行。For()倾向于假设您的操作主要受CPU限制,因此它将使用一种根据您的机器拥有多少CPU内核而调整的并行度。但是HTTP请求往往是IO绑定的,所以大部分时间都花在等待目标机器将信息发送回您身上

这意味着这是一个使用异步处理的好机会。试着这样做:

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

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

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

    为什么要执行200个GET请求?你能不能把请求合并成一个请求,在服务器上进行处理,然后把你想要输出的内容返回给用户?不,我不能,这是练习的一部分。。我需要快速完成200个请求,并且在最佳实践中,处理结果和输出。为什么选择不异步执行此操作?它应该是同步的有什么原因吗?因为对于1个请求和3个请求,我不认为需要它,但我想现在它会快得多。我只是想找一个简单的例子来说明如何做,谢谢你的回答。这是一项家庭作业,但完成所有要求仍需40-50秒。。这正常吗?另外,1个请求和3个请求的选项应该同步完成,对吗?@OfekAgmon:很难说这是否正常,因为我不知道目标服务器是如何设置的。请求返回通常需要多长时间?当目标服务器处理并发请求时,它能看到多少性能下降?我看不出有任何理由对1或3个请求进行任何不同的处理:HTTP请求本质上是一种异步操作,因此从性能角度来看,没有任何令人信服的理由来强制您的代码同步运行。好的,非常感谢。还有一件小事——我在其中放置您发布的两行代码(Enumerable.Range)的方法具有“public async Task execFeature”签名,并且有一条警告说我没有使用“Wait”,因此该方法将同步运行。这有关系吗?因为我所有的方法都是异步的,并且返回某种类型的任务,program.cs中的第一个调用是featureService.startService().Wait()。应该是这样吗?谢谢million@OfekAgmon:如果该方法已经是
    async
    ,则应使用
    (wait Task.WhenAll(classNameTasks))
    而不是
    Task.WhenAll(classNameTasks.Result
    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));