2012-12-10 15 views
9

I tworzenie przykładowego przykładu połączenia z linkiem za pomocą WebClient przy użyciu async i czekam na metodę teraz chcę dołączyć również anulować funkcję asynchronicznego połączenia. Ale nie jestem w stanie uzyskać tokena CancellationTokenSource i dołączyć do tego tokena DownloadStringTaskAsync. Oto jest mój kod może ktoś mi powiedzieć, jak to osiągnąć.Jak załączyć metodę AnulowanieTokenSource do pobieraniaStringTaskAsync i anulować wywołanie asynchroniczne?

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

Kiedy nazywa mój przycisk Anuluj cts.Cancel wywołanie DownloadStringTaskAsync nie zostanie anulowane. Dlaczego przycisk anulowania nie może anulować wywołań asynchronicznych?

+0

Ty nie używasz 'CancellationTokeSource' w jakikolwiek sposób, w jaki jest' WebClient' powinien wiedzieć powinien zrezygnować, jeśli nie powiedzieć, że go ? – svick

+0

Pozdrowienia dla twojej odpowiedzi. Ale próbowałem przekazać token jako parametr metody DownloadStringTaskAsync, ale nie ma przeciążenia dla tej metody, która go obsługuje. W związku z tym nie otrzymałem sposobu używania tokenu anulowania za pomocą metody DownloadStringTaskAsync. Czy możesz zaproponować mi kilka dobrych książek, aby przeczytać wszystkie nowe aktualizacje w C# z możliwościami TAP. –

Odpowiedz

14

Możliwości asynchroniczne WebClient predate .Net 4.5, więc obsługuje tylko częściowo tylko the Task-based Asynchronous Pattern. Obejmuje to posiadanie własnego mechanizmu anulowania: the CancelAsync() method, który działa nawet z nowymi metodami -TaskAsync. Aby wywołać tę metodę, gdy CancellationToken zostanie anulowane, można użyć its Register() method:

cts.Token.Register(wc.CancelAsync); 

Jako alternatywę, można użyć nowego HttpClient, jak Stephen zasugerował, który w pełni obsługuje TAP, w tym CancellationToken s.

3

WebClient nie obsługuje anulowania. Polecam skorzystać z nowszego typu, takie jak 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) 
... 

Sposób GetAsync domyślnie nie będzie kompletny, dopóki nie czyta całą odpowiedź, więc linia await response.Content.ReadAsStringAsync rzeczywiście zakończyć synchronicznie.

0

metody rozszerzeń na podstawie svick za odpowiedź:

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); 
} 
Powiązane problemy