多线程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.
不能保证类是线程安全的。从MSDN:
不保证任何实例成员是线程安全的
为每个请求使用一个HttpWebRequest
。如果你对不同的网站有很多请求,使用WebClient
或HttpWebRequest
并不重要。
如果你对同一个网站做了很多请求,它仍然没有看起来那么低效。HttpWebRequest
重用连接(它隐藏在引擎盖下面)。微软使用一种叫做服务点的东西,你可以通过HttpWebRequest访问它们。ServicePoint财产。如果你点击属性定义你会看到ServicePoint
文档在那里你可以微调每个网站的连接数等等