C# 多线程应用程序中的HttpWebRequest.GetResponse性能问题

C# 多线程应用程序中的HttpWebRequest.GetResponse性能问题,c#,.net,C#,.net,当从不同的线程为不同的URL调用HttpWebRequest.GetResponse方法时,它的性能非常差。 例如,如果我们有一个线程并执行url1,它需要3sec。 如果并行执行url1和url2,则需要10秒,第一个请求在8秒后结束,第二个请求在10秒后结束 如果我们有10个URL url1,url2。。。url0它需要1分钟4秒!!!第一个请求在50秒后结束 我使用GetResponse方法。 我尝试设置默认连接限制,但没有帮助。 如果使用BeginGetRequest/EndGetRes

当从不同的线程为不同的URL调用HttpWebRequest.GetResponse方法时,它的性能非常差。 例如,如果我们有一个线程并执行url1,它需要3sec。 如果并行执行url1和url2,则需要10秒,第一个请求在8秒后结束,第二个请求在10秒后结束

如果我们有10个URL url1,url2。。。url0它需要1分钟4秒!!!第一个请求在50秒后结束

我使用GetResponse方法。 我尝试设置默认连接限制,但没有帮助。 如果使用BeginGetRequest/EndGetResponse方法,它的工作速度非常快,但仅当从一个线程调用此方法时。如果从不同的角度来看,它也是非常缓慢的。 我需要一次执行来自多个线程的Http请求

在每个线程中执行相同的代码。如果只有一个线程,GetResponse方法工作得非常快。 此外,URL中的IP地址对于每个线程都是不同的。 如果编译并运行以下代码,您将看到请求一个接一个地被处理。第一次执行3秒,第二次执行8秒,第三次执行15秒。。。。 i、 e.多线程没有任何好处

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);
            }

        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
Net系统;
使用System.IO;
使用System.Xml;
运用系统反思;
使用系统线程;
使用System.Collections.Generic;
使用System.Collections.Specialized;
使用系统集合;
命名空间HttpRequestExample
{
类HttpPerformer
{
私有线程线程=null;
HttpWebRequest httpRequest=null;
公共无效开始(字符串url)
{
线程=新线程(新线程开始(WorkerThread));
thread.Name=url;
thread.Start();
}
public void WorkerThread()
{
尝试
{
HttpWebRequest req=(HttpWebRequest)WebRequest.Create((string)thread.Name);
Console.WriteLine(DateTime.Now+“:在获取响应“+thread.Name”之前);
HttpWebResponse resp=(HttpWebResponse)req.GetResponse();
Console.WriteLine(DateTime.Now+“:在获取响应“+线程名”之后);
}
捕获(例外e)
{
Console.WriteLine(DateTime.Now+”:异常:“+e.Message+thread.Name);
}
}
}
类HttpAccessUtils
{
公共静态布尔设置AllowUnsafeheaderParsing20()
{
//获取包含内部类的程序集
Assembly-aNetAssembly=Assembly.GetAssembly(typeof(System.Net.Configuration.SettingsSection));
如果(aNetAssembly!=null)
{
//使用程序集获取内部类的内部类型
键入aSettingsType=aNetAssembly.GetType(“System.Net.Configuration.setingssectioninternal”);
if(aSettingsType!=null)
{
//使用内部静态属性获取内部设置类的实例。
//如果静态实例未创建,则属性将为我们创建它。
对象anInstance=aSettingsType.InvokeMember(“节”,
BindingFlags.Static | BindingFlags.GetProperty | BindingFlags.NonPublic,null,null,new object[]{});
if(anInstance!=null)
{
//找到私有bool字段,该字段告诉框架不安全,是否应允许头解析
FieldInfo aUseUnsafeHeaderParsing=aSettingsType.GetField(“useUnsafeHeaderParsing”,BindingFlags.NonPublic | BindingFlags.Instance);
if(aUseUnsafeHeaderParsing!=null)
{
aUseUnsafeHeaderParsing.SetValue(一个状态,true);
返回true;
}
}
}
}
返回false;
}
}
班级计划
{
静态void Main(字符串[]参数)
{
HttpAccessUtils.SetAllowUnsafeHeaderParsing20();
ServicePointManager.UseNagleAlgorithm=true;
ServicePointManager.Expect100Continue=true;
ServicePointManager.CheckCertificatereJournalist=true;
ServicePointManager.DefaultConnectionLimit=200;//ServicePointManager.DefaultPersistentConnectionLimit;
ServicePointManager.MaxServicePoints=100;
Console.WriteLine(ServicePointManager.MaxServicePoints);
ArrayList a=新的ArrayList(150);
对于(int i=100;i<220;i++)
{
a、 加(”http://207.242.7.“+i.ToString());
}
for(int i=0;i

С有人遇到过这样的问题吗?谢谢您的建议。

您需要在收到响应流后关闭连接,否则连接将保持长时间打开。这可能是速度缓慢的原因。

收到响应后,需要关闭连接。这似乎是问题的原因。

您能发布有问题的代码吗