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?