我正在嘗試取消通過共享HttpClient使用發(fā)出的多個異步 Web 請求 (GET) CancellationTokens,在命令行應(yīng)用程序中,完整框架,.net 4.7.1,C# 7.3,VS 2017。我的示例運(yùn)行了幾個并行任務(wù),每個任務(wù)都使用異步通過 Http 不斷下載一些數(shù)據(jù)GetAsync(),ReadAsStringAsync()但我使用例如ReadAsByteArrayAsync().終止是通過掛鉤Console.CancelKeyPress和取消 my CancellationTokenSource.盡管出于某種原因這看起來很簡單,但我無法理解它并想出一個產(chǎn)生可靠結(jié)果的解決方案。有時一切都按預(yù)期關(guān)閉,即所有任務(wù)都完成(取消),但更多時候不是關(guān)閉只是看似掛起。在沒有調(diào)試器(有/沒有調(diào)試)的情況下運(yùn)行會終止應(yīng)用程序,但不是以我預(yù)期的方式。更少的任務(wù)意味著更可能干凈地關(guān)閉。在處于“掛起”狀態(tài)時暫停調(diào)試中的所有線程似乎表明某些線程卡在其中,GetAsync()但要確切了解發(fā)生了什么有點(diǎn)困難。實(shí)際上,應(yīng)用程序如何退出并不重要,但我想了解這一點(diǎn)并能夠始終如一地產(chǎn)生干凈且受控的關(guān)閉,這在我看來使用此構(gòu)造似乎是可能的,但我很可能錯過了一些細(xì)節(jié)。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貢獻(xiàn)1876條經(jīng)驗(yàn) 獲得超7個贊
好吧,通過 StackOverflow 躲避我自己又一次奏效了。
Ctrl+C如果沒有通過 取消args.Cancel = true,則終止應(yīng)用程序,因此它與HttpClient或 的關(guān)系絕對為零CancellationToken。
修復(fù)方法很簡單:
Console.CancelKeyPress += (sender, args) =>
{
args.Cancel = true;
Console.WriteLine("Stopped by user");
cancellationTokenSource.Cancel(true);
};
- 1 回答
- 0 關(guān)注
- 255 瀏覽
添加回答
舉報
0/150
提交
取消