并行处理时的WebRequest超时

时间:2016-05-26 11:25:07

标签: c# multithreading parallel-processing task-parallel-library

我只想了解并行处理如何在c#中工作。这是我的代码示例:

Parallel.For(0, 1000, index =>
{
    try
    {
        var url = "some exemplary url";
        HttpStatusCode statusCode;
        HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
        StringBuilder data = new StringBuilder();

        using (HttpWebResponse myWebResponse = (HttpWebResponse)request.GetResponse())
        {
            statusCode = myWebResponse.StatusCode;
            if (myWebResponse.GetResponseStream() != null)
            {
                StreamReader streamReader = new StreamReader(myWebResponse.GetResponseStream());

                using (streamReader)
                {
                    string line = string.Empty;
                    while ((line = streamReader.ReadLine()) != null)
                    {
                        data.Append(line);
                    }
                }
            }
            MailMessage msg = new MailMessage();

            msg.Subject = "subject";
            msg.From = new MailAddress("no-reply@domain.co.uk");
            msg.To.Add("name.name@domain.com");
            msg.Body = data.ToString();
            msg.IsBodyHtml = true;
            var newSmtp = new SmtpClient();
            newSmtp.Send(msg);

            Interlocked.Increment(ref count);
        }
    }
    catch (Exception e)
    {
    }
});

代码的技术性在这里并不重要,因为它工作正常。但是,请求一些示例性URL"是相当耗时的,在处理了+ -30个请求后,我得到了"操作已超时"异常抛出。当我更改Parallel for循环并添加MaxDegreeOfParallelism选项时如此

Parallel.For(0, 1000, new ParallelOptions { MaxDegreeOfParallelism = 4 }, index =>
{

我不再抛出异常。所以,我试图弄清楚为什么添加此选项会修复工作流程?在我看来它与线程管理有关吗?我对它的理解是,当我没有指定线程数时,在等待前一个线程完成之前创建新线程?我是对的,还是我的代码有问题?

1 个答案:

答案 0 :(得分:2)

同时传出HTTP连接的数量有限制。 如果您想增加线程数,则应在创建DefaultConnectionLimit之前增加HttpWebRequest

System.Net.ServicePointManager.DefaultConnectionLimit

您可以使用<connectionManagement>配置代码https://msdn.microsoft.com/en-us/library/fb6y0fyc.aspx

<configuration>
  <system.net>
    <connectionManagement>     
      <add address = "*" maxconnection = "2" />
    </connectionManagement>
  </system.net>
</configuration>