WebClientがWebサイトのソースコードをダウンロードし、GUIをフリーズしないように非同期的にフィルタリングする例を教えてください。
-
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 を使用してUIの相互作用を確認していることに注意してください。メインUIスレッドで実行されます。この場合、メッセージボックスが表示されます。
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();
所属していません StackOverflow