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);
}
}