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