Você poderia me dar um exemplo de uma WebClient download de um código-fonte do site e filtrando algo de forma assíncrona, para não congelar a GUI?
-
06-07-2019 - |
Pergunta
Eu li alguns dos artigos no MSDN, mas eles não são bem o que eu preciso agora.
Você poderia me mostrar uma aplicação simples que os downloads de um site asyncchronously (WebClient.DownloadDataAsync) e depois filtra a tag título do site?
Eu não posso fazer isso para a vida de mim, e eu só estou tentando ver um modelo clara.
Solução
Você pode achar que é mais fácil de usar DownloadStringAsync. Dessa forma, você pode analisar o HTML como uma string ao invés de ter que lidar com codificação de si mesmo.
Tanto quanto como analisar o título, você pode achar que um pouco mais difícil de fazer, uma vez .NET não tem um built-in HTML parser. Você poderia tentar alguns RegEx ou utilização XMLReader, mas aqueles pode ser problemático se você tiver mal formado ou conteúdo complicado.
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);
Outras dicas
Aqui é uma solução completa que usos delegados assíncronos . Observe que eu estou usando Control.Invoke para garantir que todas as interações de UI são executadas no thread principal UI, neste caso exibir uma caixa de mensagem.
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();