在我故意捕获WebServiceException以让我的应用程序继续之后,我以某种方式得到死锁/挂起。但是,即使应用程序仍然存在。做一个webservice挂起,似乎它仍然试图从之前的调用做一些事情。 我尝试使用CancellationTokenSource,但似乎没有解决我的问题。
RetryHandler:
public class RetryHandler : DelegatingHandler
{
private const int MaxRetries = 2;
public RetryHandler(HttpMessageHandler innerHandler)
: base(innerHandler)
{
}
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
CancellationToken cancellationToken)
{
HttpResponseMessage response = null;
Exception lastException = null;
for (var i = 0; i < MaxRetries; i++)
{
try
{
response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
}
catch (Exception ex)
{
lastException = ex;
}
if (IsSuccessful(response))
{
return response;
}
}
throw GetException(response, lastException);
}
两次调用帖子使我的程序挂起:
public async Task<T> Post<T>(
string path,
HttpContent content,
string username,
string token,
HttpMessageHandler handler)
{
var client = new HttpClient(new RetryHandler(handler));
var authString = GetAuthenticationString(username, token);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", authString);
AddUsernameAndTokenToClientRequestHeader(client, username, token);
client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", content.Headers.ContentType.MediaType);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));
var result = await client.PostAsync(new Uri(path), content, _cancelHttpRequests.Token).ConfigureAwait(false);
var resultContent = result.Content.ReadAsStringAsync().Result;
return JsonConvert.DeserializeObject<T>(resultContent);
}
答案 0 :(得分:2)
这里发生的事情是,虽然您正在捕获异常,并且应该让您的应用程序继续运行,但服务本身会继续它的工作,异步,所以即使您试图强制使用该服务继续,它仍将继续尝试完成所有期望的行动。
在你的情况下:造成死锁。取消令牌在这里不会有帮助,因为您的服务正在运行异步,并且您已经通过捕获异常来停止它,因此,您基本上不使用此令牌。
解决这个问题的两种方法:
要么在获得异常时断开服务,这会强制服务关闭。
或尝试以同步方式使用您的服务,以便您可以在需要时停止服务,这样可以确保在您停止服务时不会执行任何其他工作。