'While loop program flow

I'm having trouble with my program flow in a while loop I created.

while (reader.Read())
{
    // Store scenario information
    int Id = (int)reader["ScenarioID"];
    string Data = reader["ScenarioData"].ToString();
    string Url = "http://google.com";

    // Initialize result information
    int HasSucceeded = 0;
    var screenshot = new Byte[] { };

    // Navigate to webBrowser
    webBrowser2.Navigate(Url);
    webBrowser2.DocumentCompleted += WebBrowserDocumentCompleted;

    // Do test
    TestScenarios(Url, HasSucceeded);

    // Take screenshot
    TakeScreenshot(screenshot);

    // Insert results
    InsertResults(Id, HasSucceeded, screenshot);

    // Mark scenario for deletion
    MarkScenario(Id);
}

private void WebBrowserDocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs Url)
{
    MessageBox.Show("Operation has completed!");
}

The expected flow of the program should be

  1. Read an item in the table
  2. Initialize some variables/store some values
  3. Navigate the webBrowser control toe the URL
  4. When the webBrowser control is finished, do a test
  5. Take a screenshot
  6. Insert results into new table
  7. Mark the item in the original table for deletion
  8. Loop back to #1 until all items have been covered.

However, what is happening is everything in the while loop is running properly in order except for the webBrowser2.Navigate line, which does not show the Url until the while loop has exited. Immediately after the Url shows, 5 sequential messages "Operation has completed" (for the 5 items in the table) appear. How can I fix my flow?



Solution 1:[1]

Try this solution. Wrap your loop in another thread than UI thread. then make use of AutoResetEvent

new Thread(() =>
{
    AutoResetEvent signal = new AutoResetEvent(false);
    while (reader.Read())
    {
        // Store scenario information
        int Id = (int)reader["ScenarioID"];
        string Data = reader["ScenarioData"].ToString();
        string Url = "http://google.com";

        // Initialize result information
        int HasSucceeded = 0;
        var screenshot = new Byte[] { };

        Action action = () =>
        {
             webBrowser2.Tag = signal;
             // Navigate to webBrowser
             webBrowser2.Navigate(Url);
             webBrowser2.DocumentCompleted -= WebBrowserDocumentCompleted;
             webBrowser2.DocumentCompleted += WebBrowserDocumentCompleted;
        };
        webBrowser2.Invoke(action);

        signal.WaitOne();//Wait till it finishes

        // Do test
        TestScenarios(Url, HasSucceeded);

        // Take screenshot
        TakeScreenshot(screenshot);

        // Insert results
        InsertResults(Id, HasSucceeded, screenshot);

        // Mark scenario for deletion
        MarkScenario(Id);
    }
}).Start();

    private void WebBrowserDocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs Url)
    {
        MessageBox.Show("Operation has completed!");
        ((AutoResetEvent)((WebBrowser)sender).Tag).Set();
    }

I asked worker thread to wait till the document loads then continue execution. simple.

Hope this helps

Solution 2:[2]

The Navigate method is probably queuing an event which will be later handled on the same thread your code is running in (the UI thread). You may have to put your code into a separate background worker thread to allow the UI events to be processed before your loop is finished.

Solution 3:[3]

I recomend you to ckeck the async and await operation if you are devleloping in .NET 4.5 Frammework. This propably will solve your problem. Async and Await in MSDN

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Colin D Bennett
Solution 3 oimitro