I am using this method to instantiate a web browser programmatically, navigate to a url and return a result when the document has completed.
How would I be able to s
I'm trying to take benefit from Noseratio's solution as well as following advices from Stephen Cleary.
Here is the code I updated to include in the code from Stephen the code from Noseratio regarding the AJAX tip.
First part: the Task NavigateAsync
advised by Stephen
public static Task NavigateAsync(this WebBrowser @this, string url)
{
var tcs = new TaskCompletionSource();
WebBrowserDocumentCompletedEventHandler subscription = null;
subscription = (_, args) =>
{
@this.DocumentCompleted -= subscription;
tcs.TrySetResult(args.Url.ToString());
};
@this.DocumentCompleted += subscription;
@this.Navigate(url);
return tcs.Task;
}
Second part: a new Task NavAjaxAsync
to run the tip for AJAX (based on Noseratio's code)
public static async Task NavAjaxAsync(this WebBrowser @this)
{
// get the root element
var documentElement = @this.Document.GetElementsByTagName("html")[0];
// poll the current HTML for changes asynchronosly
var html = documentElement.OuterHtml;
while (true)
{
// wait asynchronously
await Task.Delay(POLL_DELAY);
// continue polling if the WebBrowser is still busy
if (webBrowser.IsBusy)
continue;
var htmlNow = documentElement.OuterHtml;
if (html == htmlNow)
break; // no changes detected, end the poll loop
html = htmlNow;
}
return @this.Document.Url.ToString();
}
Third part: a new Task NavAndAjaxAsync
to get the navigation and the AJAX
public static async Task NavAndAjaxAsync(this WebBrowser @this, string url)
{
await @this.NavigateAsync(url);
await @this.NavAjaxAsync();
}
Fourth and last part: the updated Task GetUrlAsync
from Stephen with Noseratio's code for AJAX
async Task GetUrlAsync(string url)
{
using (var wb = new WebBrowser())
{
var navigate = wb.NavAndAjaxAsync(url);
var timeout = Task.Delay(TimeSpan.FromSeconds(5));
var completed = await Task.WhenAny(navigate, timeout);
if (completed == navigate)
return await navigate;
return null;
}
}
I'd like to know if this is the right approach.