我正在尝试取消通过共享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 关注
- 235 浏览
添加回答
举报
0/150
提交
取消