2012-12-10 6 views
9

I un creare un esempio di esempio per chiamare il collegamento utilizzando WebClient utilizzando async e attendere il metodo ora voglio allegare anche la funzionalità di cancellazione delle chiamate asincrone. Ma non sono in grado di ottenere il token CancellationTokenSource e collegare DownloadStringTaskAsync a questo token di cancellazione. Seguendo è il mio codice qualcuno può dirmi come realizzare questo.Come allegare CancellationTokenSource al metodo DownloadStringTaskAsync e annullare la chiamata asincrona?

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

Quando il mio pulsante Annulla chiama cts.Cancel la chiamata DownloadStringTaskAsync non viene annullata. Perché il pulsante Annulla non è in grado di annullare le chiamate asincrone?

+0

Non stai utilizzando la 'CancellationTokeSource' in alcun modo, come è il' WebClient' supposto sapere che dovrebbe annullare quando non dite che ? – svick

+0

Grazie svick per la tua risposta. Ma ho provato a passare il token come parametro del metodo DownloadStringTaskAsync ma non c'è sovraccarico per questo metodo che lo supporta. Quindi non stavo ottenendo come utilizzare il token di cancellazione con il metodo DownloadStringTaskAsync. Puoi suggerirmi alcuni buoni libri per leggere tutti questi nuovi aggiornamenti in C# con le funzionalità di TAP. –

risposta

14

Le funzionalità async di WebClient precedono .Net 4.5, quindi supporta solo the Task-based Asynchronous Pattern solo parzialmente. Questo include il proprio meccanismo di annullamento: the CancelAsync() method, che funziona anche con i nuovi metodi -TaskAsync. Per chiamare questo metodo quando un CancellationToken viene annullata, è possibile utilizzare its Register() method:

cts.Token.Register(wc.CancelAsync); 

In alternativa, è possibile utilizzare la nuova HttpClient, come Stephen ha suggerito, che supporta pienamente TAP, compresa CancellationToken s.

3

WebClient non supporta la cancellazione. Vi consiglio di usare un nuovo tipo come ad esempio 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) 
... 

Il metodo GetAsync di default non verrà completata fino a quando si legge l'intera risposta, quindi la linea await response.Content.ReadAsStringAsync sarà effettivamente completare in modo sincrono.

0

metodi di estensione in base alla risposta del svick:

public static async Task<string> DownloadStringTaskAsync(this WebClient webClient, string url, CancellationToken cancellationToken) { 
    cancellationToken.Register(webClient.CancelAsync); 
    return await webClient.DownloadStringTaskAsync(url); 
} 

public static async Task<string> DownloadStringTaskAsync(this WebClient webClient, Uri uri, CancellationToken cancellationToken) { 
    cancellationToken.Register(webClient.CancelAsync); 
    return await webClient.DownloadStringTaskAsync(uri); 
}