Не могли бы вы привести пример, когда WebClient загружает исходный код сайта и фильтрует что-то асинхронно, чтобы не заморозить графический интерфейс?
-
06-07-2019 - |
Вопрос
Я прочитал некоторые статьи на MSDN, но они не совсем то, что мне сейчас нужно.
Не могли бы вы показать мне простое приложение, которое загружает сайт асинхронно (WebClient.DownloadDataAsync), а затем фильтрует тег TITLE сайта?
Я не могу сделать это ради своей жизни, и я просто пытаюсь увидеть четкую модель.
Решение
Возможно, вам будет проще использовать DownloadStringAsync. Таким образом, вы можете анализировать HTML как строку, а не заниматься кодированием самостоятельно.
Что касается синтаксического анализа заголовка, вам может показаться, что это сделать немного сложнее, поскольку в .NET нет встроенного анализатора HTML. Вы можете попробовать RegEx или использовать XMLReader, но это может быть проблематично, если у вас искаженный или хитрый контент.
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);
Другие советы
Вот полное решение, в котором используются асинхронные делегаты . Обратите внимание, что я использую Control.Invoke , чтобы гарантировать, что любые взаимодействия пользовательского интерфейса выполняются в основном потоке пользовательского интерфейса, в этом случае отображается окно сообщения.
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();