![](/img/trans.png)
[英]Why is the task is not cancelled when I call CancellationTokenSource's Cancel method in async method?
[英]How to attach CancellationTokenSource to DownloadStringTaskAsync method and cancel the async call?
我創建了一個示例示例,使用async和await方法使用WebClient調用鏈接現在我也想附加取消異步調用功能。 但我無法獲得CancellationTokenSource令牌並將DownloadStringTaskAsync附加到此取消令牌。 以下是我的代碼可以告訴我如何實現這一目標。
private async void DoWork()
{
this.Cursor = Cursors.WaitCursor;
Write("DoWork started.");
cts = new CancellationTokenSource();
WebClient wc = new WebClient();
string result = await wc.DownloadStringTaskAsync(new Uri("http://gyorgybalassy.wordpress.com"));
if (result.Length < 100000)
{
Write("The result is too small, download started from second URL.");
result = await wc.DownloadStringTaskAsync(new Uri("https://www.facebook.com/balassy"));
}
Write("Download completed. Downloaded bytes: " + result.Length.ToString());
Write("DoWork ended.");
this.Cursor = Cursors.Default;
}
private void btnCancel_Click(object sender, EventArgs e)
{
Write("Cancellation started.");
this.cts.Cancel();
Write("Cancellation ended.");
}
當我的取消按鈕調用cts.Cancel時,不會取消DownloadStringTaskAsync調用。 為什么取消按鈕無法取消異步通話?
WebClient
的異步功能早於.Net 4.5,因此它僅部分支持基於任務的異步模式 。 這包括擁有自己的取消機制: CancelAsync()
方法 ,它甚至可以使用新的-TaskAsync
方法。 要在CancellationToken
時調用此方法,可以使用其Register()
方法 :
cts.Token.Register(wc.CancelAsync);
作為替代方案,您可以使用新的HttpClient
,正如Stephen建議的那樣,它完全支持TAP,包括CancellationToken
。
WebClient
不支持取消。 我建議你使用更新的類型,如HttpClient
:
...
cts = new CancellationTokenSource();
string result;
using (var client = new HttpClient())
using (var response = await client.GetAsync("http://gyorgybalassy.wordpress.com", cts.Token))
{
result = await response.Content.ReadAsStringAsync();
}
if (result.Length < 100000)
...
默認情況下, GetAsync
方法在讀取整個響應之前不會完成,因此await response.Content.ReadAsStringAsync
行實際上將同步完成。
基於svick答案的擴展方法:
public static async Task<string> DownloadStringTaskAsync(this WebClient webClient, string url, CancellationToken cancellationToken) {
using (cancellationToken.Register(webClient.CancelAsync)) {
return await webClient.DownloadStringTaskAsync(url);
}
}
public static async Task<string> DownloadStringTaskAsync(this WebClient webClient, Uri uri, CancellationToken cancellationToken) {
using (cancellationToken.Register(webClient.CancelAsync)) {
return await webClient.DownloadStringTaskAsync(uri);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.