本文介绍了为什么HttpClient的出现在这里死锁?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个便携式类库,需要接触到特定于平台的API来发送HTTP请求作出的API。下面是我写的做的WinRT的HTTP POST方法:

I have an API made in a portable class library which needs to reach out to platform specific APIs for sending HTTP requests. Here is the method I wrote to do an HTTP POST on WinRT:

   public bool Post(IEnumerable<KeyValuePair<string, string>> headers, string data)
    {
        bool success = false;
        HttpClient client = new HttpClient(new HttpClientHandler {AllowAutoRedirect = false});
        foreach (var header in headers)
        {
            client.DefaultRequestHeaders.Add(header.Key, header.Value);
        }

        try
        {
            var task=client.PostAsync(endpoint, new StringContent(data, Encoding.UTF8, "text/xml")).ContinueWith( postTask =>
                    {
                        try
                        {
                            postTask.Wait(client.Timeout); //Don't wait longer than the client timeout.
                            success = postTask.Result.IsSuccessStatusCode;
                        }catch {}
                    }, TaskContinuationOptions.LongRunning);
            task.ConfigureAwait(false);
            task.Wait(client.Timeout);

        }
        catch
        {
            success = false;
        }

        return success;
    }

这虽然下的任何这种压力虽然。这似乎在内部死锁。就像如果我创建5个线程和发送POST请求了出来,这种方法将得到一个会做的没有,但超时。内容永远不会到达服务器,并且永远不会执行。继续代码。不过,如果我连续或者甚至有2个或3个线程运行,将工作确定。看来,在它抛出了更多的线程,虽然使性能成倍糟糕

This exhibits an interesting problem though when put under any kind of stress though. It appears to deadlock internally. Like if I create 5 threads and send POST requests out of them, this method will get to where it will do nothing but timeout. Content never reaches the server, and the .Continue code is never executed. However, if I run it serially or maybe even with 2 or 3 threads it will work OK. It seems that the more threads thrown at it though make the performance exponentially worse

正是我在做什么错在这里?

Exactly what am I doing wrong here?

推荐答案

我不认为这是你的问题是,但它可能是,它真的很容易实现并测试它。默认情况下的Windows设置为2和2个以上的线程可以在连接池被锁定最大的网络连接。您可以添加到您的应用程序配置

I don't think this is where you problem is but it could be and it's really easy to implement and test it out. By default Windows sets the Max Network connections to 2 and with more than 2 threads you could be locking on the connection pool. You can add this to your app config

<system.net>
  <connectionManagement>
    <add address="*" maxconnection="300" />
   </connectionManagement>
</system.net>

或代码,你可以做到这一点。

or in code you can do this

ServicePointManager.DefaultConnectionLimit = 300

我也认为评论出了继续等待。我不认为这是必要的。

I'd also consider commenting out the wait in the continue with. I don't think it's necessary.

try
{
    //Comment this line out your handling it in the outside task already
    //postTask.Wait(client.Timeout); //Don't wait longer than the client timeout.
    success = postTask.Result.IsSuccessStatusCode;
 }catch {}



最后,如果以上两个事情不工作我。ð尝试注释掉的代码

And finally if the 2 things above don't work I'd try commenting out the this code.

//Task.ConfigureAwait(false);



这可能是Task.Wait加设置Task.ConfigureAwait(假)会引起一些组合一种僵局,但我为什么没有专家。我只知道,我有一个运行一些非常相似的代码多线程就好了,我没有Task.ConfigureAwait(假)在我的代码,主要是因为我尝试了HttpClient库,但没有升级到.NET 4.5所以等待是不可用的。

It could be that the combination of Task.Wait plus setting Task.ConfigureAwait(false) is causing some kind of deadlock but I'm no expert on why. I just know that I have some really similar code that runs multi-threaded just fine and I don't have Task.ConfigureAwait(false) in my code, mostly because I tried out the HttpClient library but didn't upgrade to .NET 4.5 so await isn't available.

这篇关于为什么HttpClient的出现在这里死锁?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-28 10:44