簡體   English   中英

如何將CancellationTokenSource附加到DownloadStringTaskAsync方法並取消異步調用?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM