0

I need to let the webBrowser navigate to several different but similiar URL's of one website, fill out a form, click on the send Button, and read the next site to find out if the previous step was successfull or not. On success the loop have to stop.

Fist i was stuck at getting webBrowser.Navigate("url"); to work in a loop. Since the page need some time to load it have to be asynchronous.

I am really new to the whole asyncronous stuff, so I need help.

I have found this solution on https://stackoverflow.com/a/15936400/4972402 so I took it and put my code into it for filling out the form and clicking the submit button.

public partial class Form1 : Form
{
    public struct WebBrowserAwaiter
    {
        private readonly WebBrowser _webBrowser;
        private readonly string _url;

        private readonly TaskAwaiter<string> _innerAwaiter;

        public bool IsCompleted
        {
            get
            {
                return _innerAwaiter.IsCompleted;
            }
        }

        public WebBrowserAwaiter(WebBrowser webBrowser, string url)
        {
            _url = url;
            _webBrowser = webBrowser;
            _innerAwaiter = ProcessUrlAwaitable(_webBrowser, url);
        }

        public string GetResult()
        {
            return _innerAwaiter.GetResult();

        }

        public void OnCompleted(Action continuation)
        {
            _innerAwaiter.OnCompleted(continuation);
        }

        private TaskAwaiter<string> ProcessUrlAwaitable(WebBrowser webBrowser, string url)
        {
            TaskCompletionSource<string> taskCompletionSource = new TaskCompletionSource<string>();
            var handler = new WebBrowserDocumentCompletedEventHandler((s, e) =>
            {
                // TODO: put custom processing of document here
                taskCompletionSource.SetResult(e.Url + ": " + webBrowser.Document.Title);
            });
            webBrowser.DocumentCompleted += handler;
            taskCompletionSource.Task.ContinueWith(s => { webBrowser.DocumentCompleted -= handler; });

            webBrowser.Navigate(url);
            return taskCompletionSource.Task.GetAwaiter();
        }
    }

    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        ProcessUrlsAsync(new[] { "http://google.com", "http://microsoft.com", "http://yahoo.com" })
            .Start();
    }

    private Task ProcessUrlsAsync(string[] urls)
    {
        return new Task(() =>
        {
            foreach (string url in urls)
            {
                var awaiter = new WebBrowserAwaiter(webBrowser1, url);
                string result = awaiter.GetResult();

                MessageBox.Show(result);
            }
        });
    }
}   
    }

The Problem now is When i do this:

        private Task ProcessUrlsAsync(string[] urls)
    {
        return new Task(() =>
        {
            foreach (string url in urls)
            {
                var awaiter = new WebBrowserAwaiter(webBrowser1, url, this.currentKunde);
                string result = awaiter.GetResult();
                if (result != "failed")
                { break; }
                else
                {
                    MessageBox.Show(result);
                }
            }
        });
    }

private TaskAwaiter<string> ProcessUrlAwaitable(WebBrowser webBrowser, string url)
    {
        TaskCompletionSource<string> taskCompletionSource = new TaskCompletionSource<string>();
        var handler = new WebBrowserDocumentCompletedEventHandler((s, e) =>
        {
            // TODO: put custom processing of document here
            if (webBrowser.Document.Title == "Title")
            {
                        webBrowser.ScriptErrorsSuppressed = false;
                        webBrowser.Document.GetElementById("Name").SetAttribute("Value", this._currentCustomer.Displayedname);
                        webBrowser.Document.GetElementById("EMail").SetAttribute("Value", this._currentCustomer.Email);

                        //Turns off CheckInput()
                        webBrowser.Document.GetElementsByTagName("form")[2].SetAttribute("onsubmit", "");

                        //Clicks on the submit button
                        webBrowser.Document.GetElementById("sendbutton").InvokeMember("click");
            }
            else
            {
                //Do other stuff and return "success"

            }
            taskCompletionSource.SetResult("failed");
        });

How Can I make the Handler get fired again after the ckick, so it will return a "success" and stop the loop?

Community
  • 1
  • 1
Enrager
  • 1
  • 1
  • Go through the list of examples/links I posted [here](http://stackoverflow.com/a/22262976/1768303). – noseratio Jun 04 '15 at 18:02
  • 1
    Thank you very much! I will solve this problem based on your Solution: http://stackoverflow.com/a/19063643 – Enrager Jun 05 '15 at 09:08

0 Answers0