2010-02-18 45 views
2
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(baseurl + url); 
req.Timeout = 1000 * 10; 
HttpWebResponse response = (HttpWebResponse)req.GetResponse(); 
Stream str = response.GetResponseStream(); 
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument(); 
doc.Load(str); 
response.Close(); 
string imgurl = doc.DocumentNode.SelectSingleNode("//div[@class='one-page']/a/img[@class='manga-page']").Attributes["src"].Value; 
req = (HttpWebRequest)HttpWebRequest.Create(imgurl); 
req.Timeout = 1000 * 10; 
response = (HttpWebResponse)req.GetResponse(); 
str = response.GetResponseStream(); 
Image img = Image.FromStream(str); 
response.Close(); 
return img; 

我在一个循环中运行这段代码(使用多个线程)下载约4000图像,它出色的作品的第数百但后来(在不同的时间点为每次我试图)它突然停止工作,并且对“req.GetResponse()”的每次调用都会导致TimeoutException。我不知道为什么发生这种情况,不知道可能会出现什么问题或如何处理。任何帮助将不胜感激。的WebRequest sudenly停止工作

我用它来运行这个功能(这就是所谓的GETPAGE(int)和被称为c.GetPage(T))是如下代码:

for (int j = 0; j < 2; j++) 
{ 
    BackgroundWorker bw = new BackgroundWorker(); 
    num[bw] = j; 
    bgs.Add(bw); 
    bw.DoWork += (object sender, DoWorkEventArgs doargs) => 
    { 
     int t = -1; 
     lock (lockObjForQueueOperations) 
     { 
      if (images.Count != 0) 
       t = images.Dequeue(); 
     } 
     if(t < 0) 
     { 
      doargs.Result = false; 
      return; 
     } 
     currently[sender] = t; 
     Image img; 
     try { img = c.GetPage(t); } 
     catch (Exception e) 
     { 
      lock (lockObjForQueueOperations) 
      { 
       images.Enqueue(t); 
      } 
      lock (Console.Title) 
      { 
       if (num[sender] == 0) Console.ForegroundColor = ConsoleColor.Cyan; 
       else if (num[sender] == 1) Console.ForegroundColor = ConsoleColor.Yellow; 
       Console.WriteLine("**ERR: Error fetshing page {0}, errormsg: {1}", t, e.Message); 
       Console.ForegroundColor = ConsoleColor.White; 
      } 
      doargs.Result = true; 
      Thread.Sleep(1000*2); 
      return; 
     } 
     lock (Console.Title) 
     { 
      if (num[sender] == 0) Console.ForegroundColor = ConsoleColor.Cyan; 
      else if (num[sender] == 1) Console.ForegroundColor = ConsoleColor.Yellow; 
      Console.WriteLine("\t\tLoaded page {0} of {1}.", t + 1, c.PagesCount); 
      Console.ForegroundColor = ConsoleColor.White; 
     } 
     string imgpath = Path.Combine(ndir, "Page " + (t + 1) + ".png"); 
     img.Save(imgpath, System.Drawing.Imaging.ImageFormat.Png); 
     img.Dispose(); 
     doargs.Result = true; 
    }; 
    bw.RunWorkerCompleted += (object sender, RunWorkerCompletedEventArgs runargs) => 
    { 
     if ((bool)runargs.Result) bw.RunWorkerAsync(); 
     else 
     { 
      finnishedworkers++; 
      if (finnishedworkers == 2) restetter.Set(); 
      bw.Dispose(); 
     } 
    }; 
    bw.RunWorkerAsync(); 
} 
+1

这可能是由您的ISP或网站主机中的DDOS保护引起的。 – SLaks 2010-02-18 22:28:50

+0

嗯,这就是我最初的想法,但后来我尝试进入我的程序试图从我的浏览器进入的同一页面,它的工作,但仍然我的程序超时。 – Alxandr 2010-02-18 23:08:01

+0

@Alxandr,我面临同样的问题。你有没有找到解决这个问题的办法? – Somnath 2012-12-21 06:08:57

回答

2

在HttpWebRequest的Timeout属性的单位是毫秒。目前将其设置为10,000仅仅是10秒,根据带宽和数据大小以及正在运行的代码的复杂程度,这可能还不够。我说试着先增加一点。

+0

资源在一秒内加载。我设置了超时时间,因为我厌倦了等待我的时间错误。 – Alxandr 2010-02-18 23:08:36

+0

另外我试图在没有设置超时的情况下运行代码,但是给我例外的时间太长(我只是在等待异常,根本没有发生任何事情......)。 – Alxandr 2010-02-18 23:22:26

2

你有一个糟糕的设计。不要为每个请求创建线程,请尝试调用BeginGetResponse。该框架将处理从线程池分配线程来处理您的请求。

到ServicePointManager.SetDefaultConnectionLimit调用(?)不知道这个加入了一些像100

创建相匹配的连接限制数的计数的信号。

在你的函数调用BeginGetResponse刚刚获得BeginGet之前您的通话添加到semaphore.WaitOne(通话)...

在你EndGetResponse()处理器,调用semaphore.Release(),以允许下一个请求接着说。

你可能正在用自己的所有线程耗尽线程池。监视你的进程,看看你是否不能执行,总共只能使用5-10个线程。也许你可以记录Thread.Current.ThreadID来查看SAME线程如何处理多个请求。

做了这十亿次。真。

+0

我不觉得我只用3个线程一直在耗尽线程池吗?或者,每次调用“RunWorkerAsync”时,后台工作者是否会创建一个新线程? – Alxandr 2010-02-19 00:31:51