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

Выходное окно, как это:

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. 

Я хочу нажать btn_cancel и отменить задание запуска и ждать начала закончить задачу.

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

Вероятно, у вас нет [«Только мой код»] (https://msdn.microsoft.com/en-us/library/dn457346. aspx), или вы что-то неправильно сделали в блоке catch 'btn_download_Click', чтобы вызвать исключения. –

1

WebClient не принимает ОтменаToken, что странно. Вместо этого у него есть метод CancelAsync, который вы можете позвонить для отмены ожидающих вызовов.

Похоже, вам нужно будет хранить ссылку на свой веб-клиент и называть этот метод нажатием кнопки отмены.

+0

Вам не нужно его поддерживать, просто используйте ['CancellationToken.Register'] (https://msdn.microsoft.com/en-us/library/dd321635 (v = vs.110) .aspx) и вызовите функцию изнутри делегата, просто передайте токен в функцию вниз по цепочке. –

+0

@ScottChamberlain, определенно, приятно. Раньше этого не использовали. Это определенно абстрагировало бы детали реализации. – Jonesopolis

+0

Мне очень жаль. Я изучаю C#, и я не знаю, как я вставляю CancellationToken.Register мои методы. Можете ли вы объяснить мне или пример? –

 Смежные вопросы

  • Нет связанных вопросов^_^