Project的目的很简单,根据 http://rolia.net 找到论坛入口URI =>从所有论坛中找到“科技领域杂谈”URI=> 在“科技领域杂谈”帖子中找到我的第一个帖子URI=> 显示我的帖子的原始HTML信息
每一步都是一个单独的异步操作,每一步都依靠上一步操作的结果
比较费时间的是根据原始的HTML Parse出需要的URI,不过如果你对LINQ很熟悉,这也就是分分钟的事情,不过在这个程序里这一块是凑或完成的,因为是为了演示async + await异步操作,这一步不是重点
这是一个WPF的Project,自己创建一个WPF的Project,分别把XAML和Code Behind Copy进去就好,直接可以运行。第一次运行整个window会卡住,我也不知道为什么,可能是WebClient在后台建立Socket连接,但是第二次、第三次就好了。在windows phone 里我没遇到过这种情况
第一个按钮是传统的异步方式,第二个按钮是Async+Await方式
XAML:
Code Behind:
每一步都是一个单独的异步操作,每一步都依靠上一步操作的结果
比较费时间的是根据原始的HTML Parse出需要的URI,不过如果你对LINQ很熟悉,这也就是分分钟的事情,不过在这个程序里这一块是凑或完成的,因为是为了演示async + await异步操作,这一步不是重点
这是一个WPF的Project,自己创建一个WPF的Project,分别把XAML和Code Behind Copy进去就好,直接可以运行。第一次运行整个window会卡住,我也不知道为什么,可能是WebClient在后台建立Socket连接,但是第二次、第三次就好了。在windows phone 里我没遇到过这种情况
第一个按钮是传统的异步方式,第二个按钮是Async+Await方式
XAML:
<Window x:Class="WpfApplication1.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="300" Width="300"> <StackPanel> <Button Content="Go to Rolia, Normal Async Usage" x:Name="butonNormalAsync" Click="butonNormalAsync_Click"/> <Button Content="Go to Rolia, Async + Await" x:Name="buttonAsyncAwait" Click="buttonAsyncAwait_Click"/> <TextBox x:Name="textBlock1" Height="200" TextWrapping="Wrap" ScrollViewer.HorizontalScrollBarVisibility="Visible"/> </StackPanel> </Window>
Code Behind:
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Shapes; namespace WpfApplication1 { /// <summary> /// Interaction logic for Window1.xaml /// </summary> public partial class Window1 : Window { public Window1() { InitializeComponent(); } string baseForumURI = "http://www.rolia.net"; // 论坛入口的URI string forumEntryURI; // should be http://www.rolia.net/f // 论坛URI string scienceForumEntryURI; // 科技领域杂谈的URI string firstThreadURL; // 我的第一篇帖子的URI string htmlString; // 传统的异步方式,就一个字:乱 private void butonNormalAsync_Click(object sender, RoutedEventArgs e) { WebClient wc = new WebClient(); wc.DownloadDataCompleted += (s, e1) => { htmlString = System.Text.Encoding.GetEncoding("UTF-8").GetString(e1.Result); forumEntryURI = getForumEntryURI(htmlString); WebClient wc1 = new WebClient(); wc1.DownloadDataCompleted += (s2, e2) => { htmlString = System.Text.Encoding.GetEncoding("UTF-8").GetString(e2.Result); scienceForumEntryURI = getScientForumEntry(htmlString); WebClient wc2 = new WebClient(); wc2.DownloadDataCompleted += (s3, e3) => { htmlString = System.Text.Encoding.GetEncoding("UTF-8").GetString(e3.Result); firstThreadURL = getFirstThreadURL(htmlString); //ok now, we came to the last step: show the content of my thread WebClient wc3 = new WebClient(); wc3.DownloadDataCompleted += (s4, e4) => { htmlString = System.Text.Encoding.GetEncoding("UTF-8").GetString(e4.Result); buttonAsyncAwait.Dispatcher.BeginInvoke(new Action(() => textBlock1.Text = htmlString)); }; //从我的第一篇帖子的URI download content wc3.DownloadDataAsync(new Uri(firstThreadURL)); }; // step 3: 从“科技领域杂谈” 找到我的第一篇帖子 wc2.DownloadDataAsync(new Uri(scienceForumEntryURI)); }; // step 2: 从论坛列表找到“科技领域杂谈” wc1.DownloadDataAsync(new Uri(forumEntryURI)); }; // step 1: 从rolia.net找到论坛入口 wc.DownloadDataAsync(new Uri(baseForumURI)); } // Async + Await 异步方式 private async void buttonAsyncAwait_Click(object sender, RoutedEventArgs e) { WebClient wc = new WebClient(); // step 1: 从rolia.net找到论坛入口 byte[] resultBytes = await wc.DownloadDataTaskAsync(baseForumURI); htmlString = System.Text.Encoding.GetEncoding("UTF-8").GetString(resultBytes); forumEntryURI = getForumEntryURI(htmlString); // step 2: 从论坛列表找到“科技领域杂谈” resultBytes = await wc.DownloadDataTaskAsync(forumEntryURI); htmlString = System.Text.Encoding.GetEncoding("UTF-8").GetString(resultBytes); scienceForumEntryURI = getScientForumEntry(htmlString); // step 3: 从“科技领域杂谈” 找到我的第一篇帖子 resultBytes = await wc.DownloadDataTaskAsync(scienceForumEntryURI); htmlString = System.Text.Encoding.GetEncoding("UTF-8").GetString(resultBytes); firstThreadURL = getFirstThreadURL(htmlString); //从我的第一篇帖子的URI download content resultBytes = await wc.DownloadDataTaskAsync(firstThreadURL); htmlString = System.Text.Encoding.GetEncoding("UTF-8").GetString(resultBytes); // show the raw content of my thread in the textBox textBlock1.Text = htmlString; } // parse HTML to ForumEntryURI string getForumEntryURI(string htmlString) { int index1 = htmlString.IndexOf("枫下论坛"); int index2 = htmlString.Substring(0,index1).LastIndexOf(@"<a"); string result = htmlString.Substring(index2, index1 - index2); result = result.Split(' ').First(s => s.Contains("href")).TrimEnd('>','\n','\t').Split('=').Last().Trim('\"'); return string.Format("{0}{1}",baseForumURI, result); } // parse HTML to ScientForumEntry private string getScientForumEntry(string htmlString) { int index1 = htmlString.IndexOf("科技领域杂谈"); int index2 = htmlString.Substring(0, index1).LastIndexOf(@"<a"); string result = htmlString.Substring(index2, index1 - index2); result = result.Split(' ').First(s => s.Contains("href")).Substring("href=".Length).Trim('\''); return string.Format("{0}/{1}", forumEntryURI, result); } // parse HTML to FirstThreadURL private string getFirstThreadURL(string htmlString) { int index1 = htmlString.IndexOf("binghongcha76"); index1 = htmlString.Substring(0, index1).LastIndexOf(@"<a"); int index2 = htmlString.Substring(0, index1).LastIndexOf(@"<a"); string result = htmlString.Substring(index2, index1 - index2); result = result.Split(' ').First(s => s.Contains("href")).Substring("href=".Length).Trim('\''); return string.Format("{0}/{1}", forumEntryURI, result); } } }