我正在尝试取消通过共享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");
}
}
}
幕布斯6054654
相关分类