线程化HTTPWebRequests

时间:2013-11-03 13:49:27

标签: c# .net multithreading httpwebrequest

我有一个程序,它永久地向服务器发送http请求并分析响应。由于我需要发送大量请求,我想做并行的http请求。我尝试了一些像Parallel.ForEach,使用longrunningoption创建任务等等,但我总是有同样的问题,它太慢了。 我正在使用httpwebrequest类并进行测试,我比较了一个线程执行50个请求所需的时间,然后是更多线程相同的时间。 1个线程为这50个请求花费了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 Threads,他们应该并行发送请求,每个线程应该为50个请求花费1500ms,就像1个线程应用程序一样。这不可能吗?

1 个答案:

答案 0 :(得分: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毫秒。