当从不同的线程调用不同的URL时,HttpWebRequest.GetResponse方法的性能非常差。 例如,如果我们有一个线程并执行url1,则需要3秒。 如果我们在parallet中执行url1和url2,它需要10秒,第一个请求在8秒后结束,在10秒后结束第二个请求。HttpWebRequest.GetResponse在多线程应用程序中的性能问题
如果我们exutet 10个URL url1,url2,... url0它需要1分4秒!!!第一个请求在50秒后结束!
我使用GetResponse方法。 我试过了DefaultConnectionLimit
但它没有帮助。 如果使用BeginGetRequest/EndGetResponse方法,它的工作速度非常快,但前提是从一个线程调用此方法。如果来自不同,它也是非常缓慢的。 我需要一次执行多个线程的Http请求。
在每个线程中执行相同的代码。如果只有一个线程的GetResponse方法工作得非常快。 对于每个线程,URL中的IP addreses也不相同。 如果您编译并运行以下代码,您将看到请求逐个处理。拳头执行3秒,第二次8秒,第三次15秒.... 即从多线程没有收益。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Xml;
using System.Reflection;
using System.Threading;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Collections;
namespace HttpRequestExample
{
class HttpPerformer
{
private Thread thread = null;
HttpWebRequest httpRequest = null;
public void start(string url)
{
thread = new Thread(new ThreadStart(WorkerThread));
thread.Name = url;
thread.Start();
}
public void WorkerThread()
{
try
{
HttpWebRequest req = (HttpWebRequest)WebRequest.Create((string)thread.Name);
Console.WriteLine(DateTime.Now + " : before get response " + thread.Name);
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
Console.WriteLine(DateTime.Now + " : after get response " + thread.Name);
}
catch (Exception e)
{
Console.WriteLine(DateTime.Now + " : Exception : " + e.Message + thread.Name);
}
}
}
class HttpAccessUtils
{
public static bool SetAllowUnsafeHeaderParsing20()
{
//Get the assembly that contains the internal class
Assembly aNetAssembly = Assembly.GetAssembly(typeof(System.Net.Configuration.SettingsSection));
if (aNetAssembly != null)
{
//Use the assembly in order to get the internal type for the internal class
Type aSettingsType = aNetAssembly.GetType("System.Net.Configuration.SettingsSectionInternal");
if (aSettingsType != null)
{
//Use the internal static property to get an instance of the internal settings class.
//If the static instance isn't created allready the property will create it for us.
object anInstance = aSettingsType.InvokeMember("Section",
BindingFlags.Static | BindingFlags.GetProperty | BindingFlags.NonPublic, null, null, new object[] { });
if (anInstance != null)
{
//Locate the private bool field that tells the framework is unsafe header parsing should be allowed or not
FieldInfo aUseUnsafeHeaderParsing = aSettingsType.GetField("useUnsafeHeaderParsing", BindingFlags.NonPublic | BindingFlags.Instance);
if (aUseUnsafeHeaderParsing != null)
{
aUseUnsafeHeaderParsing.SetValue(anInstance, true);
return true;
}
}
}
}
return false;
}
}
class Program
{
static void Main(string[] args)
{
HttpAccessUtils.SetAllowUnsafeHeaderParsing20();
ServicePointManager.UseNagleAlgorithm = true;
ServicePointManager.Expect100Continue = true;
ServicePointManager.CheckCertificateRevocationList = true;
ServicePointManager.DefaultConnectionLimit = 200; //ServicePointManager.DefaultPersistentConnectionLimit;
ServicePointManager.MaxServicePoints = 100;
Console.WriteLine(ServicePointManager.MaxServicePoints);
ArrayList a = new ArrayList(150);
for (int i = 100; i < 220; i++)
{
a.Add("http://207.242.7." + i.ToString());
}
for (int i = 0; i < a.Count; i++)
{
HttpPerformer hp = new HttpPerformer();
hp.start((string)a[i]);
}
}
static void performRequest(object url)
{
try
{
HttpWebRequest req = (HttpWebRequest)WebRequest.Create((string)url);
Console.WriteLine(DateTime.Now + " : before get response " + url);
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
Console.WriteLine(DateTime.Now + " : after get response " + url);
}
catch (Exception e)
{
Console.WriteLine(DateTime.Now + " : Exception : " + e.Message + (string)url);
}
}
}
}
有没有人遇到过这样的问题?谢谢你的任何建议。
添加到帖子 – Nikita 2010-06-05 20:21:37
的代码你可以发布有问题的_your_代码吗?并且你发布的代码甚至不会编译,因为你错过了一个'('。 – Oded 2010-06-05 20:22:00
邮政编码,它会在我们的机器上重现问题。如有必要,使用文件共享服务。 – 2010-06-05 20:29:37