0

This foreach loop checks a webpage and sees if there are any images then downloads them. How do i stop it? When i press the button it continues the loop forever.

 private void button1_Click(object sender, EventArgs e)
    {
        WebBrowser browser = new WebBrowser();
        browser.DocumentCompleted +=browser_DocumentCompleted;
        browser.Navigate(textBox1.Text);           
    }

    void browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
        WebBrowser browser = sender as WebBrowser;
        HtmlElementCollection imgCollection = browser.Document.GetElementsByTagName("img");
        WebClient webClient = new WebClient();

        int count = 0; //if available
        int maximumCount = imgCollection.Count;
        try
        {
                foreach (HtmlElement img in imgCollection)
                {
                    string url = img.GetAttribute("src");
                    webClient.DownloadFile(url, url.Substring(url.LastIndexOf('/')));

                     count++;
                     if(count >= maximumCount)
                          break;
                }
        }
        catch { MessageBox.Show("errr"); }
    }
FJam
  • 736
  • 3
  • 13
  • 32
  • 1
    What is "the button" that you speak of? – Jashaszun Jul 26 '13 at 21:59
  • it is just a button to execute the code. – FJam Jul 26 '13 at 22:01
  • 1
    When do you want to stop? – Tim S. Jul 26 '13 at 22:02
  • 4
    This doesn't look like an infinite loop to me... – Heinzi Jul 26 '13 at 22:03
  • 1
    Can you post the code for how `imgCollection` is populated, please? – cokeman19 Jul 26 '13 at 22:03
  • i added the `imgcollection`, it just runs forever. – FJam Jul 26 '13 at 22:06
  • 2
    Are you sure it's not just taking a really long time? Have you tried breakpoints? – Joel Coehoorn Jul 26 '13 at 22:07
  • Can you put a breakpoint on the line with the `foreach`, run your code, and then tell us how many elements your `imgCollection` has? Also, some of the images might be really big. It doesn't look to me like you're using asynchronous downloading, so that might be the problem. – Jashaszun Jul 26 '13 at 22:08
  • no, its not redownloading images. While its is running if i delete an image it will redownload it. – FJam Jul 26 '13 at 22:10
  • Seem to me that the `DocumentCompleted` event is probably firing more than once. Based on the code you are showing, the loop is not infinate, but if the event is being fired over and over, you will execute this function multiple times. Check out this post for ways to handle if the event is firing too many times. http://stackoverflow.com/questions/2328835/why-is-webbrowser-documentcompleted-firing-twice – Caleb Jul 27 '13 at 00:34
  • Remove `catch { MessageBox.Show("errr"); }`. That is discarding the error so you don't know what is going wrong. – Dour High Arch Jul 27 '13 at 01:19

3 Answers3

0

use the break; keyword to break out of a loop

Cam Bruce
  • 5,632
  • 19
  • 34
  • how will i know when to use the `break;` – FJam Jul 26 '13 at 22:02
  • If you don't know when to stop, then you have to find out why the loop is infinite. If you keep a count of iterations, you can pick an arbitrary number of iterations, then break out. – Cam Bruce Jul 26 '13 at 22:08
0

You do not have an infinite loop, you have an exception that is being thrown based on how you are writing the file to disk

private void button1_Click(object sender, EventArgs e)
{
    WebBrowser browser = new WebBrowser();
    browser.DocumentCompleted += browser_DocumentCompleted;
    browser.Navigate("www.google.ca");
}

void browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    WebBrowser browser = sender as WebBrowser;
    HtmlElementCollection imgCollection = browser.Document.GetElementsByTagName("img");
    WebClient webClient = new WebClient();

    foreach (HtmlElement img in imgCollection)
    {
        string url = img.GetAttribute("src");
        string name = System.IO.Path.GetFileName(url);
        string path = System.IO.Path.Combine(Environment.CurrentDirectory, name);
        webClient.DownloadFile(url, path);
    }
}

That code works fine on my environment. The issue you seemed to be having was when you were setting the DownloadFile filepath, you were setting it to a value like `\myimage.png', and the webclient could not find the path so it threw and exception.

The above code drops it into the current directory with the extension name.

jrbeverly
  • 1,611
  • 14
  • 20
0

Maybe the Event browser.DocumentCompleted cause the error, if the page refreshes the event gets fired again. You could try to deregister the event.

void browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{    
    WebBrowser browser = sender as WebBrowser;

    browser.DocumentCompleted -= browser_DocumentCompleted;

    HtmlElementCollection imgCollection = browser.Document.GetElementsByTagName("img");
    WebClient webClient = new WebClient();

    foreach (HtmlElement img in imgCollection)
    {
        string url = img.GetAttribute("src");
        string name = System.IO.Path.GetFileName(url);
        string path = System.IO.Path.Combine(Environment.CurrentDirectory, name);
        webClient.DownloadFile(url, path);
    }
}