多个并发线程与Web查询问题

时间:2018-09-12 16:09:18

标签: c# .net multithreading concurrency .net-core

我正在构建相当复杂的并发系统,偶然发现了一个奇怪的问题。我会尽量简单。

  1. 我在.net core 2.1上有一个单实例控制台应用程序
  2. 我有一个HttpClient实例
  3. 我设置了以下参数: System.Net.ServicePointManager.DefaultConnectionLimit = int.MaxValue; System.Net.ServicePointManager.ReusePort = true; HttpClient.DefaultRequestHeaders.ConnectionClose = true; HttpClient.SetBearerToken(SOME_TOKEN);
  4. 我有一个线程(A),该线程使用 ThreadPool / new Thread()在内部使用单个HTTP GET查询不断创建多达30个新的并发线程(都尝试了),然后将结果放入ConcurrentQueue变量中。
  5. 我还有另一个线程(B),该线程从队列中读取数据,并通过内部一个HTTP POST查询不断创建多达30个新的并发线程。

问题是我遵循以下工作流程:

  1. A线程运行良好,将结果与队列一起馈入。所有线程运行正常。
  2. 在A线程启动之后,B线程开始为POST创建子线程。
  3. A线程完成其工作,所有线程均已完成。此时,由B线程创建的所有线程都挂在 await client.PostAsync()方法上。
  4. 应用程序挂起约10秒钟。
  5. VS日志显示多个线程0x35e0已退出,代码为0(0x0)。消息提示先前使用的线程正在释放。为什么这么久?!
  6. 应用程序会暂停20秒
  7. 由B线程创建的第一个线程开始失败,然后所有其他B线程开始正常执行。

尝试:

  1. 一次将并发线程数减少到5-10可解决问题,但完全破坏了并发性能。

  2. 我看到日志中的线程计数并且没有溢出,A和B一次最多30个线程(最多大约60个线程)

  3. 试图降低 System.Net.ServicePointManager.DefaultConnectionLimit 参数,但无济于事。

看起来有些东西阻止了POST查询,然后它们又正常地再次着急。请就此问题提出建议。谢谢。

PS:我处理 Flickr 查询。可能是他们的某些访问限制吗?无论如何,POST挂起看起来都很奇怪,只是挂起而没有单次通过。

1 个答案:

答案 0 :(得分:0)

由于Polyfun,将应用程序限制为不断运行的线程数量较少,而不是无休止地创建数百个线程是一个好主意。

尽管速度减慢的真正原因是当查询期间的一些可弃资源未被处置时的资源阻塞。包括由客户管理的较低级别代码保留的 HttpWebResponse 实体。