我正在嘗試取消通過共享HttpClient使用發出的多個異步 Web 請求 (GET) CancellationTokens,在命令行應用程序中,完整框架,.net 4.7.1,C# 7.3,VS 2017。我的示例運行了幾個并行任務,每個任務都使用異步通過 Http 不斷下載一些數據GetAsync(),ReadAsStringAsync()但我使用例如ReadAsByteArrayAsync().終止是通過掛鉤Console.CancelKeyPress和取消 my CancellationTokenSource.盡管出于某種原因這看起來很簡單,但我無法理解它并想出一個產生可靠結果的解決方案。有時一切都按預期關閉,即所有任務都完成(取消),但更多時候不是關閉只是看似掛起。在沒有調試器(有/沒有調試)的情況下運行會終止應用程序,但不是以我預期的方式。更少的任務意味著更可能干凈地關閉。在處于“掛起”狀態時暫停調試中的所有線程似乎表明某些線程卡在其中,GetAsync()但要確切了解發生了什么有點困難。實際上,應用程序如何退出并不重要,但我想了解這一點并能夠始終如一地產生干凈且受控的關閉,這在我看來使用此構造似乎是可能的,但我很可能錯過了一些細節。using System;using System.Linq;using System.Net;using System.Net.Http;using System.Threading;using System.Threading.Tasks;namespace HttpClientAsyncTest{ class Program { static async Task<int> Main() { using (var cancellationTokenSource = new CancellationTokenSource()) { Console.CancelKeyPress += (sender, a) => { Console.WriteLine("Stopped by user"); cancellationTokenSource.Cancel(); }; var task = RunAsync(cancellationTokenSource); Console.WriteLine("Running - Press CTRL+C to stop"); await task; } Console.WriteLine("All done, exiting"); return 0; } private static async Task RunAsync(CancellationTokenSource cts) { using (var client = new HttpClient()) { try { var tasks = Enumerable.Range(1, 10).Select(id => ProcessBatchAsync(client, id, cts.Token)); await Task.WhenAll(tasks); } catch (OperationCanceledException) { Console.WriteLine("Operation cancelled somehow"); } } }
1 回答

幕布斯6054654
TA貢獻1876條經驗 獲得超7個贊
好吧,通過 StackOverflow 躲避我自己又一次奏效了。
Ctrl+C如果沒有通過 取消args.Cancel = true,則終止應用程序,因此它與HttpClient或 的關系絕對為零CancellationToken。
修復方法很簡單:
Console.CancelKeyPress += (sender, args) =>
{
args.Cancel = true;
Console.WriteLine("Stopped by user");
cancellationTokenSource.Cancel(true);
};
- 1 回答
- 0 關注
- 266 瀏覽
添加回答
舉報
0/150
提交
取消