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?
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 CancellationToken
s.
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.
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