Could you give me an example of a WebClient downloading a website source code and filtering something asynchronously as to not freeze the GUI?
-
06-07-2019 - |
Question
I've read some of the articles on MSDN but they're not quite what I need right now.
Could you show me a simple application that downloads a website asyncchronously (WebClient.DownloadDataAsync) and then filters the TITLE tag of the site?
I can't do this for the life of me, and I'm just trying to see a clear cut model.
Solution
You may find it easier to use DownloadStringAsync. That way, you can parse the HTML as a string rather than having to deal with encoding yourself.
As far as how to parse the title, you may find that a bit more difficult to do, since .NET doesn't have a built-in HTML parser. You could try some RegEx or use XMLReader, but those can be problematic if you have malformed or tricky content.
var client = new WebClient();
client.DownloadStringCompleted += (s, args) => {
if (args.Error == null && !args.Cancelled) {
var regex = new Regex("<title>(?<title>.*?)</title>");
var match = regex.Match(args.Result);
if (match.Success)
{
var myTitle = match.Groups["title"].Value;
// ...
}
}
};
client.DownloadStringAsync(url);
OTHER TIPS
Here is a complete solution that uses asynchronous delegates. Notice that I am using Control.Invoke to ensure that any UI interactions are performed on the main UI thread, in this case displaying a message box.
var button = new Button {Text = "Run"};
button.Click +=
(sender, e) =>
{
var fetchTitle = new Func<string, string>(
address =>
{
var html = new WebClient().DownloadString(address);
var match = Regex.Match(html, "<title>(.*)</title>");
return match.Groups[1].Value;
});
var displayTitle = new Action<string>(
title => MessageBox.Show(title));
fetchTitle.BeginInvoke(
"http://stackoverflow.com",
result =>
{
var title = fetchTitle.EndInvoke(result);
if (button.InvokeRequired)
{
button.Invoke(displayTitle, title);
}
else
{
displayTitle(title);
}
},
null);
};
new Form {Controls = {button}}.ShowDialog();