1

を始めた私はリストでタスクを開始し、Task.WhenAllC#でタスクをキャンセルするにはリスト<>

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

を待って、それはリストでタスクを開始する私のコードです。

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

と私のダウンロード方法

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

このような出力ウィンドウ:私はbtn_cancelクリックして、タスクを開始キャンセルし、仕上がりを待ちたい

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. 

は、タスクを開始しました。

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

あなたの質問は何ですか? –

+0

'Task.WaitAll(doclist.Select(doc => DownloadFileAsync(doc))。ToArray(トークン)を使用してください。 ' –

+0

@MatiasCicero私はそんなことはできませんhttp://prntscr.com/c9iiql –

答えて

2

キャンセルトークンをコールチェーンに引き渡し、可能であればキャンセルトークンを使用して、キャンセルコールを登録してから、WebClient.CancelAsync()に電話してダウンロードをキャンセルする必要があります。

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

ありがとう、ありがとう。私は試して働いた。しかし、出力ウィンドウは次のようにいっぱいです。http://prntscr.com/c9j0pg –

+0

["Just My Code"](https://msdn.microsoft.com/en-us/library/dn457346)はありません。 aspx)がオンになっているか、 'btn_download_Click' catchブロックで何か間違っていたことがあります。 –

1

WebClientは、奇妙なCancelationTokenを使用しません。代わりに、保留中の通話をキャンセルするために電話をかけることができる方法CancelAsyncがあります。

ウェブクライアントのリファレンスを保持しておき、キャンセルボタンをクリックしてそのメソッドを呼び出す必要があるようです。

+0

あなたはそれを守る必要はありません。['CancellationToken.Register'](https://msdn.microsoft.com/en-us/library/dd321635(v = vs.110).aspx)とデリゲートの内部から関数を呼び出すには、トークンを関数のチェーンに渡します。 –

+0

@ScottChamberlain、間違いなく良い。以前はそれを使わなかった。それは間違いなく実装の詳細を抽象化します。 – Jonesopolis

+0

大変申し訳ございません。私はC#を学んでいますが、CancellationTokenを挿入する方法はわかりません。自分のメソッドを登録してください。あなたは私のことを説明することができますか? –

関連する問題