1

Ich begann Aufgabe mit Listen und warten Task.WhenAllC# Abbrechen Aufgabe mit gestarteter List <>

private async void btn_download_Click(object sender, EventArgs e) 
    { 
     . 
     . 
     . 
     await DownloadMultipleFilesAsync(old_json); 
     Console.WriteLine("Download completed."); 
    } 

und das ist mein Code, die Aufgabe mit der Liste zu starten.

private async Task DownloadMultipleFilesAsync(List<media> doclist) 
    { 
     var token = cancelTokenSource.Token; 
     await Task.WhenAll(doclist.Select(doc => DownloadFileAsync(doc))); 
     btn_download.Enabled = true; 
    } 

und meine Download-Methode

private async Task DownloadFileAsync(media media) 
{ 
    . 
    . 
    . 
    Console.WriteLine(media.no + media_ext + " started."); 
    webClient.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials; 
    await webClient.DownloadFileTaskAsync(new Uri(media.url), @downloadToDirectory); 
    Console.WriteLine(media.no + media_ext + " finished."); 
    . 
    . 
    . 
} 

Das Ausgabefenster wie folgt aus:

1.jpg started. 
2.jpg started. 
3.jpg started. 
4.jpg started. 
5.jpg started. 
6.jpg started. 
7.jpg started. 
8.jpg started. 
9.jpg started. 
10.jpg started. 
11.jpg started. 
12.jpg started. 
13.jpg started. 
14.jpg started. 
15.jpg started. 
16.jpg started. 
17.jpg started. 
18.jpg started. 
19.jpg started. 
1.jpg finished. 
4.jpg finished. 
2.jpg finished. 
6.jpg finished. 
8.jpg finished. 
10.jpg finished. 
3.jpg finished. 
5.jpg finished. 
12.jpg finished. 
14.jpg finished. 
7.jpg finished. 
16.jpg finished. 
18.jpg finished. 
9.jpg finished. 
11.jpg finished. 
13.jpg finished. 
15.jpg finished. 
17.jpg finished. 
19.jpg finished. 
Download completed. 

I btn_cancel klicken möchten und Abbrechen Aufgabe und Aufgabe Ziel gestartet warten zu starten.

private void btn_cancel_Click(object sender, EventArgs e) 
{ 
    cancelTokenSource.Cancel(); 
    cancelTokenSource = new CancellationTokenSource(); 
} 
+2

Und was ist Ihre Frage? –

+0

Verwenden Sie 'Task.WaitAll (doclist.Select (doc => DownloadFileAsync (doc)). ToArray(), Token)' –

+0

@MatiasCicero kann ich nicht so verwenden http://prntscr.com/c9iiql –

Antwort

2

Was Sie tun müssen, ist das Kündigungszeichen in die Anrufkette zu geben und es dann zu verwenden, wo es möglich ist. Sie müssen auch einen Rückruf zurückrufen, um WebClient.CancelAsync() aufzurufen, um den Download abzubrechen.

private async void btn_download_Click(object sender, EventArgs e) 
{ 
    . 
    . 
    . 
    var token = cancelTokenSource.Token; 
    try 
    { 
     await DownloadMultipleFilesAsync(old_json, token); 
     Console.WriteLine("Download completed."); 
    } 
    catch(OperationCanceledException ex) 
    { 
     //If something other than our token caused the cancel bubble up the exception. 
     if(ex.CancellationToken != token) 
      throw; 
    } 
} 


private async Task DownloadMultipleFilesAsync(List<media> doclist, CancellationToken token) 
{ 
    await Task.WhenAll(doclist.Select(doc => DownloadFileAsync(doc, token)); 
    btn_download.Enabled = true; 
} 


private async Task DownloadFileAsync(media media, CancellationToken token) 
{ 
    . 
    . 
    . 
    Console.WriteLine(media.no + media_ext + " started."); 
    webClient.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials; 
    try 
    { 
     using(token.Register(() => webClient.CancelAsync())) 
     { 
      await webClient.DownloadFileTaskAsync(new Uri(media.url), @downloadToDirectory); 
     } 
    }    
    catch (WebException ex) 
    { 
     //Raise a OperationCanceledException if the request was canceled, otherwise bubble up the exception. 
     if(ex.Status == WebExceptionStatus.RequestCanceled) 
      throw new OperationCanceledException(token); 
     else 
      throw; 
    } 
    Console.WriteLine(media.no + media_ext + " finished."); 
    . 
    . 
    . 
} 
+0

Vielen Dank. Ich habe es versucht und gearbeitet. Aber Ausgabefenster ist voll wie folgt: http://printscr.com/c9j0pg –

+0

Sie haben wahrscheinlich nicht ["Just My Code"] (https://msdn.microsoft.com/en-us/library/dn457346. aspx) aktiviert oder Sie haben etwas falsches im 'btn_download_Click' catch Block gemacht, um die Ausnahmen durchzulassen. –

1

WebClient muss kein CancelationToken, die seltsam ist. Stattdessen gibt es eine Methode CancelAsync, die Sie anrufen können, um ausstehende Anrufe abzubrechen.

Scheint so, als müssten Sie einen Verweis auf Ihren webClient führen und diese Methode aufrufen, indem Sie auf die Abbrechen-Schaltfläche klicken.

+0

Sie müssen es nicht herum behalten, verwenden Sie einfach ein ['CancellationToken.Register'] (https://msdn.microsoft.com/en-us/library/dd321635 (v = vs.110) .aspx) und Rufen Sie die Funktion innerhalb des Delegaten auf, übergeben Sie das Token einfach an die Funktion in der Kette. –

+0

@ScottChamberlain, auf jeden Fall, nett. Habe das vorher nicht benutzt. Das würde die Implementierungsdetails definitiv abstrahieren. – Jonesopolis

+0

Es tut mir so leid. Ich lerne C# und ich weiß nicht, wie ich CancellationToken einfüge.Registriere meine Methoden. Kannst du mir oder einem Beispiel erklären? –

Verwandte Themen