我遇到了.NET HttpClient
类(.NET 4.5.1,System.Net.Http v4.0.0.0)的问题.我正在调用HttpClient.GetAsync
,传入一个CancellationToken
(作为Nuget包的一部分,用于抽象webservices之间的调用).如果在进行调用之前已取消令牌,则请求将在不抛出异常的情况下通过.这种行为似乎不正确.
我的测试(不完整,未完全编写 - 无异常检查):
[TestMethod] public async Task Should_Cancel_If_Cancellation_Token_Called() { var endpoint = "nonexistent"; var cancellationTokenSource = new CancellationTokenSource(); var _mockHttpMessageHandler = new MockHttpMessageHandler(); _mockHttpMessageHandler .When("*") .Respond(HttpStatusCode.OK); var _apiClient = new ApiClientService(new HttpClient(_mockHttpMessageHandler)); cancellationTokenSource.Cancel(); var result = await _apiClient.Get(endpoint, null, cancellationTokenSource.Token); }
我正在测试的方法:
public async TaskGet (string endpoint, IEnumerable > parameters = null, CancellationToken cancellationToken = default(CancellationToken)) { var builder = new UriBuilder(Properties.Settings.Default.MyEndpointHost + endpoint); builder.Query = buildQueryStringFromParameters(parameters); _httpClient.DefaultRequestHeaders.Accept.Clear(); _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); try { // After this, we really shouldn't continue. var request = await _httpClient.GetAsync(builder.Uri, cancellationToken); if (!request.IsSuccessStatusCode) { if (request.StatusCode >= HttpStatusCode.BadRequest && request.StatusCode < HttpStatusCode.InternalServerError) { throw new EndpointClientException("Service responded with an error message.", request.StatusCode, request.ReasonPhrase); } if (request.StatusCode >= HttpStatusCode.InternalServerError && (int)request.StatusCode < 600) { throw new EndpointServerException("An error occurred in the Service endpoint.", request.StatusCode, request.ReasonPhrase); } } var json = await request.Content.ReadAsStringAsync(); return JsonConvert.DeserializeObject (json); } catch (Exception ex) { throw; } }
我知道我可以在调用之前检查取消令牌的状态,HttpClient.GetAsync
如果已经请求取消则抛出.我知道我也可以注册一个委托来取消HttpClient请求.然而,似乎将令牌传递给HttpClient方法应该为我处理这个问题(或者,除此之外,重点是什么?)所以我想知道我是否遗漏了一些东西.我无权访问HttpClient
源代码.
HttpClient.GetAsync
当我传递它时,为什么不检查我的取消令牌并中止其进程?