多线程WebClient请求返回错误system.net.webeexception

本文关键字:system net webeexception 错误 返回 WebClient 请求 多线程 | 更新日期: 2023-09-27 18:03:07

我想使用WebClient下载5000多个页面。由于我希望尽可能快地完成,我试图使用多线程(在我的情况下使用BlockingCollection),但程序似乎总是在一段时间后崩溃,错误-"system.net.webeexception"。如果我添加一些Thread.Sleep(3000)延迟,它会减慢我的下载过程,并在多一点时间后返回错误。

下载一个页面通常需要2-3秒。

通常情况下,我猜我的BlockingCollection有问题,但它与其他任务一起工作很好,所以我很确定我的WebClient请求有问题。我认为单独的WebClients之间可能有某种重叠,但这只是猜测。

        Multithreading multiThread = new Multithreading(5); 
        for(int pageNumber = 1; pageNumber <= 5181; pageNumber++)
        {
            multiThread.EnqueueTask(new Action(() => //add task ("scrape the trader") to the multithread queue
            {
                using (WebClient client = new WebClient())
                {
                    client.DownloadFile("http://example.com/page=" + pageNumber.ToString(), @"C:'mypages'page " + pageNumber.ToString() + ".html");
                } 
            }));
            //I put the Thread.Sleep(123) delay here
        }

如果我添加一个较小的延迟(例如Thread.Sleep(100)),它工作得很好,但是我最终会刮掉Page # *whatever pageNumber's value is at the moment*,而不是像通常那样按顺序。

这是我的BlockingCollection(我想我从stackoverflow得到了这个代码):

class Multithreading : IDisposable
{
      BlockingCollection<Action> _taskQ = new BlockingCollection<Action>();
      public Multithreading(int workerCount)
      {
        // Create and start a separate Task for each consumer:
        for (int i = 0; i < workerCount; i++)
          Task.Factory.StartNew (Consume);
      }
      public void Dispose() { _taskQ.CompleteAdding(); }
      public void EnqueueTask (Action action) { _taskQ.Add (action); }
      void Consume()
      {
        // This sequence that we’re enumerating will block when no elements
        // are available and will end when CompleteAdding is called. 
        foreach (Action action in _taskQ.GetConsumingEnumerable())
          action();     // Perform task.
      }
}

我还尝试将所有内容放入无休止的while循环并使用try...catch语句处理错误,但显然它不会立即返回错误,但过了一段时间(不确定何时)。

下面是整个例外:

An exception of type 'System.Net.WebException' occurred in System.dll but was not handled in user code
Additional information: An exception occurred during a WebClient request.

多线程WebClient请求返回错误system.net.webeexception

不能保证类是线程安全的。从MSDN:

不保证任何实例成员是线程安全的

为每个请求使用一个HttpWebRequest。如果你对不同的网站有很多请求,使用WebClientHttpWebRequest并不重要。

如果你对同一个网站做了很多请求,它仍然没有看起来那么低效。HttpWebRequest重用连接(它隐藏在引擎盖下面)。微软使用一种叫做服务点的东西,你可以通过HttpWebRequest访问它们。ServicePoint财产。如果你点击属性定义你会看到ServicePoint文档在那里你可以微调每个网站的连接数等等