c# - 线程化 HTTPWeb 请求

标签 c# .net multithreading httpwebrequest

我有一个程序,它永久向服务器发送 http 请求并分析响应。由于我需要发送大量请求,我想做并行 http 请求。我尝试了一些方法,例如 Parallel.ForEach、使用 longrunningoption 创建任务等,但我总是遇到同样的问题,它太慢了。 我正在使用 httpwebrequest 类,为了进行测试,我比较了一个线程执行 50 个请求所需的时间,然后比较了更多线程所需的时间。对于这 50 个请求,1 个线程花费了 1500 毫秒,而 5 个线程已经花费了 1900-2500 毫秒。每个新线程/任务都会减慢速度..

    public void test()
    {
        Stopwatch stopWatch = new Stopwatch();

        stopWatch.Start();

        for (int i = 0; i < 50; i++)
        {
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create("www.thetestingurl.com");

        request.Method = "GET";

        var response = request.GetResponse();

        response.Close();            
        }

        stopWatch.Stop();

        MessageBox.Show(stopWatch.ElapsedMilliseconds.ToString());
    }

那我做错了什么?我已经了解 ServicePointManager.DefaultConnectionLimit,但这没有帮助。

编辑:

这就是我尝试创建任务的方式:

for (int i = 0; i < taskCount; i++)
{
    var task = new Task(() => test(),
        TaskCreationOptions.LongRunning);
    task.Start();
}
Task.WaitAll();

编辑:

所以,为了明确我的意思:当我在 1 个线程上运行此代码时,需要 1500 毫秒,当我使用任务、线程、线程池等时,每个线程需要超过 1500 毫秒。我想创建 x 线程,它们应该并行发送请求,并且每个线程应该花费 1500 毫秒来处理 50 个请求,就像 1 线程应用程序一样。这不可能吗?

最佳答案

我建议使用ThreadPool而不是Task或Parallel.ForEach,因为它们也使用ThreadPool,而你无法控制它。我根据您的代码准备了简单的示例,您可以将其编译为控制台应用程序:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Test1
{
    public class Class1
    {
        public void test()
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.dir.bg/");

            request.Method = "GET";

            var response = request.GetResponse();

            response.Close();
        }

        public static void Main()
        {
            CountdownEvent countDown = new CountdownEvent(50);

            Stopwatch sw = new Stopwatch();
            sw.Start();


            for (int i = 0; i < 50; i++)
            {
                //11646 ms
                //new Class1().test();

                // 502 ms
                ThreadPool.QueueUserWorkItem(DoRequest, countDown);
            }

            countDown.Wait();

            sw.Stop();

            MessageBox.Show(sw.ElapsedMilliseconds.ToString());


        }

        private static void DoRequest(Object stateInfo)
        {
            CountdownEvent countDown = (CountdownEvent)stateInfo;

            new Class1().test();

            countDown.Signal();
        }
    }


}

在我的测试中,时间从 11646 毫秒减少到 502 毫秒。

关于c# - 线程化 HTTPWeb 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19753671/

相关文章:

c# - 如何使用 sql helper 从具有 xml 的 sp 获取 xml 数据

c# - 如果文本不存在,如何在文本后添加字符串?

c# - 如何编写 C# 正则表达式以确保字符串以一个字符开头,后跟 6 位数字

c# - ViewPort3D:如何从后面的代码创建带有文本的 WPF 对象(立方体)

java - volatile 是否同步原子数据类型的数组?

c# - 如何保持 .NET 控制台应用程序运行?

c# - 为什么 hash_pbkdf2 (PHP) 的输出与 .NET/C# 实现不同

c# - 单元测试项目不是从构建服务器构建的

.net - 如何在 .NET 中读取 "drive label"或 "volume name"?

java - 在继续之前等待 Swing GUI 关闭