How to attach CancellationTokenSource to DownloadStringTaskAsync method and cancel the async call?

僤鯓⒐⒋嵵緔 提交于 2019-12-03 11:56:01

问题


I an creating a sample example to call link using WebClient using async and await method now I want to attach cancel async call functionality also. But I am not able to get CancellationTokenSource token and attach DownloadStringTaskAsync to this cancellation token. Following Is my code can anyone tell me how to accomplish this.

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

When my Cancel button calls cts.Cancel the DownloadStringTaskAsync call is not canceled. Why cancel button is not able to cancel the Async calls?


回答1:


The async capabilities of WebClient predate .Net 4.5, so it supports the Task-based Asynchronous Pattern only partially. That includes having its own cancellation mechanism: the CancelAsync() method, which works even with the new -TaskAsync methods. To call this method when a CancellationToken is canceled, you can use its Register() method:

cts.Token.Register(wc.CancelAsync);

As an alternative, you could use the new HttpClient, as Stephen suggested, which fully supports TAP, including CancellationTokens.




回答2:


WebClient doesn't support cancellation. I recommend you use a newer type such as 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)
...

The GetAsync method by default will not complete until it reads the entire response, so the await response.Content.ReadAsStringAsync line will actually complete synchronously.




回答3:


Extension methods based on svick's answer:

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


来源:https://stackoverflow.com/questions/13798539/how-to-attach-cancellationtokensource-to-downloadstringtaskasync-method-and-canc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!