【问题标题】:Get Deadlock when doing a HTTPRequest after catching WebserviceException捕获 WebserviceException 后执行 HTTPRequest 时出现死锁
【发布时间】:2015-09-02 06:03:10
【问题描述】:

在我故意捕获 WebServiceException 以让我的应用程序继续运行后,我不知何故出现了死锁/挂起。但是,即使申请继续进行。执行 web 服务挂起,它可能似乎仍在尝试从上一次调用中执行某些操作。 我尝试使用 CancellationTokenSource,但这似乎并没有解决我的问题。

重试处理程序:

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);
    }

两次调用 Post 会使我的程序挂起:

    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);        
    }

【问题讨论】:

  • 这很奇怪...应该挂在 first call.Result。检查您是否没有遗漏任何步骤。
  • 我想做什么。是捕获 WebServiceException 然后取消请求,这样它就不会挂起:天哪,这很糟糕 :(

标签: c# .net web-services c#-4.0


【解决方案1】:

这里发生的情况是,虽然您正在捕获异常,并且应该让您的应用程序继续运行,但服务本身会继续它的工作,异步,因此即使您试图强制服务继续,它仍将继续尝试完成所有所需的操作。

在您的情况下:导致死锁。取消令牌在这里无济于事,因为您的服务正在异步运行,并且您已经通过捕获异常停止了它,因此,您基本上没有对这个令牌做任何事情。

解决这个问题的两种方法:

或者,当您遇到异常时断开服务,这样会强制服务关闭。

或者尝试以同步方式使用您的服务,以便您可以在需要时停止服务,这样可以确保在您停止服务时它不会做任何额外的工作。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2021-02-23
  • 1970-01-01
  • 2015-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多