2

我有一个程序永久向服务器发送 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 个线程应用程序一样。这不可能吗?

4

1 回答 1

2

我建议使用 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 毫秒。

于 2013-11-03T18:11:05.460 回答