【问题标题】:.NET HttpClient.PostAsync() slow after 3 requests.NET HttpClient.PostAsync() 在 3 个请求后变慢
【发布时间】:2015-02-07 16:21:37
【问题描述】:

我正在使用 .NET 4.5 HttpClient 类多次向服务器发出 POST 请求。前 3 次调用运行很快,但第四次调用 await client.PostAsync(...) 时,它会挂起几秒钟,然后返回预期的响应。

using (HttpClient client = new HttpClient())
{
    // Prepare query
    StringBuilder queryBuilder = new StringBuilder();
    queryBuilder.Append("?arg=value");

    // Send query
    using (var result = await client.PostAsync(BaseUrl + queryBuilder.ToString(),
        new StreamContent(streamData)))
    {
        Stream stream = await result.Content.ReadAsStreamAsync();
        return new MyResult(stream);
    }
}

服务器代码如下:

HttpListener listener;

void Run()
{
    listener.Start();

    ThreadPool.QueueUserWorkItem((o) =>
     {
        while (listener.IsListening)
        {
            ThreadPool.QueueUserWorkItem((c) =>
            {
                var context = c as HttpListenerContext;
                try
                {
                    // Handle request
                }
                finally
                {
                    // Always close the stream
                    context.Response.OutputStream.Close();
                }
            }, listener.GetContext());
        }
    });
}

// Handle request 处插入调试语句表明服务器代码似乎没有在请求发送后立即接收。

我已经调查过是否可能是客户端没有关闭响应的问题,这意味着可以达到 ServicePoint 提供程序允许的连接数。但是,我尝试增加ServicePointManager.MaxServicePoints,但这根本没有效果。

我也发现了这个类似的问题:

.NET HttpClient hangs after several requests (unless Fiddler is active)

我不认为这是我的代码的问题 - 即使将我的代码更改为那里给出的确切内容也不能解决问题。

【问题讨论】:

  • 你试过设置ServicePointManager.DefaultConnectionLimit吗?
  • 是的,我尝试将其设置为 10,但没有任何效果
  • 使用不同的服务器 (google.com)。问题还在吗?

标签: c# .net httpwebrequest


【解决方案1】:

问题在于计划运行的Task 实例过多。

更改我的程序中的一些Task.Factory.StartNew 调用以用于运行很长时间的任务以使用TaskCreationOptions.LongRunning 选项解决了这个问题。似乎任务调度程序在将请求调度到服务器之前正在等待其他任务完成。

【讨论】:

  • 如果您用尽了线程池限制,您的应用程序就会出现严重问题。解决这个问题,而不是用 LongRunning 隐藏问题。
  • 我的应用程序的一部分正在侦听各种端口上的连接,因此我有一个线程专门用于侦听每个端口。将这些线程的任务更改为长时间运行似乎可以,因为它们是必要的?
  • 你可以这样做。这将是一个稳定的应用程序,因为负载不在池中。但是由于您正在使用带有等待的异步 IO,因此只需使用它来接受。
  • 不,我在这里使用了其他任务,而不是 HttpClient
猜你喜欢
  • 1970-01-01
  • 2020-02-04
  • 1970-01-01
  • 2014-07-08
  • 2015-12-30
  • 2017-04-15
  • 1970-01-01
  • 2017-06-24
  • 1970-01-01
相关资源
最近更新 更多