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 suspect running a processing loop on another thread will not work out well, since WebBrowser
is a UI component that hosts an ActiveX control.
When you're writing TAP over EAP wrappers, I recommend using extension methods to keep the code clean:
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;
}
Now your code can easily apply a timeout:
async Task GetUrlAsync(string url)
{
using (var wb = new WebBrowser())
{
var navigate = wb.NavigateAsync(url);
var timeout = Task.Delay(TimeSpan.FromSeconds(5));
var completed = await Task.WhenAny(navigate, timeout);
if (completed == navigate)
return await navigate;
return null;
}
}
which can be consumed as such:
private async Task GetFinalUrlAsync(PortalMerchant portalMerchant)
{
SetBrowserFeatureControl();
if (string.IsNullOrEmpty(portalMerchant.Url))
return null;
var result = await GetUrlAsync(portalMerchant.Url);
if (!String.IsNullOrEmpty(result))
return new Uri(result);
throw new Exception("Parsing Failed");
}