c# 异步调用之异步模式 Func<string, IImageRequest, string> downloadString = (address, req) =>
{
var client = new WebClient();
foreach (var header in req.Headers)
{
client.Headers.Add(header.Key, header.Value);
}
client.Credentials = req.Credentials;
client.Encoding = System.Text.Encoding.UTF8;
return client.DownloadString(address);
};
Action<SearchItemResult> addItem = item => _searchInfo.List.Add(item);
foreach (var req in GetSearchRequests())
{
downloadString.BeginInvoke(req.Url, req, ar =>//BeginInvoke:线程池中一个线程异步调用
{
try
{
string resp = downloadString.EndInvoke(ar);//downloadString异步方法执行结束,执行ar委托
var images = req.Parse(resp);
foreach (var image in images)
{
this.Dispatcher.Invoke(addItem, image);//当前线程回到主线程同步执行
}
}
catch (WebException ex) when (ex.Message.Contains("401"))
{
MessageBox.Show(errorMessage, "Registration Needed");
}
}, null);
}
c#异步调用之基于事件 foreach (var req in GetSearchRequests())
{
var client = new WebClient();
foreach (var header in req.Headers)
{
client.Headers.Add(header.Key, header.Value);
}
client.Credentials = req.Credentials;
client.DownloadStringCompleted += (sender1, e1) =>
{
try
{
string resp = e1.Result;
var images = req.Parse(resp);
foreach (var image in images)
{
_searchInfo.List.Add(image);//事件处理程序可以直接访问UI
}
}
catch (Exception ex) when (ex.InnerException?.Message.Contains("401") ?? false)
{
MessageBox.Show(errorMessage, "Registration Needed");
}
};
client.DownloadStringAsync(new Uri(req.Url));//异步变体方法 以“async”后缀;结束之后会调用事件,此方法对应DownloadStringCompleted事件
}
//异步调用之基于任务(TAP)
private async void OnTaskBasedAsyncPattern(object sender, RoutedEventArgs e)//async关键字创建了一个状态机
{
_cts = new CancellationTokenSource();
try
{
foreach (var req in GetSearchRequests())
{
var clientHandler = new HttpClientHandler
{
Credentials = req.Credentials
};
var client = new HttpClient(clientHandler);
foreach (var header in req.Headers)
{
client.DefaultRequestHeaders.Add(header.Key, header.Value);
}
var response = await client.GetAsync(req.Url, _cts.Token);//解除线程阻塞
response.EnsureSuccessStatusCode();
string resp = await response.Content.ReadAsStringAsync();//解除线程阻塞
await Task.Run(() =>//后台线程运行
{
var images = req.Parse(resp);
foreach (var image in images)
{
_cts.Token.ThrowIfCancellationRequested();
_searchInfo.List.Add(image);//UI调用问题:BindingOperations.EnableCollectionSynchronization,启用集合同步访问功能
}
}, _cts.Token);
}
}
catch (HttpRequestException ex) when (ex.Message.Contains("401"))
{
MessageBox.Show(errorMessage, "Registration Needed");
}
catch (OperationCanceledException ex)
{
MessageBox.Show(ex.Message);
}
}
|
请发表评论