先来一个经典的抓取网页,然后Parse转换内容到数组并通过绑定更新到UI的方法:
private async void OnTaskBasedAsyncPattern(object sender, RoutedEventArgs e)
{
foreach (var req in GetSearchRequests())
{
var clientHandler = new HttpClientHandler { Credentials = req.Credentials };
var client = new HttpClient(clientHandler);
var response = await client.GetAsync(req.Url, cts.Token);
string resp = await response.Content.ReadAsStringAsync();
await Task.Run(() => {
IEnumerable images = req.Parse(resp);
foreach (var image in images)
{
_searchInfo.List.Add(image);
}
}
}
}
Task.Run 中我们做了两件事情,把抓取到的内容转换成一个枚举数组,然后遍历这个数组把它们都加到与 UI 绑定的 _searchInfo 数组中。
由于 Task.Run 是在后台运行的,直接对 UI 更新会有问题,我们就需要做一些变更:把_searchInfo 的更新放到 UI thread 中。
WPF 中提供了一个简单的方法:
private object _lockList = new object();
public MainWindow()
{
InitializeComponent();
this.DataContext = _searchInfo;
BindingOperations.EnableCollectionSynchronization(_searchInfo.List, _lockList);
}