受连接池限制的处理循环

本文关键字:处理 循环 连接 | 更新日期: 2023-09-27 18:12:40

我在这里寻找一些战略帮助,因为我是TPL的新手。

情况

我有一个应用程序,它在两个不同的LOB系统之间协调数据,这些系统彼此不通信。所以,它看起来有点像:

[ System 1 ] < ----- [ App ] ----- > [ System 2 ]

在处理过程中,应用程序执行以下任务:

  1. App创建到系统1的连接。此连接必须对web应用程序进行屏幕抓取,因此它使用a和System 2,验证每个都可用。
  2. App请求系统a的id列表
  3. 这个列表是逐项浏览的。处理列表:
    1. App向系统1请求数据。该系统不提供任何服务接口,因此应用程序使用WebRequest向系统1发送GET和POST请求。除了抓取网页数据外,还可以下载文件。
    2. 使用来自系统1的数据,App通过几个web服务调用向系统2提交数据。
    3. 可能有多个呼叫,也可能有文件上传。

循环中通常有成千上万个项目。这些项之间没有依赖关系,因此它们似乎是基于Task的处理的良好候选项。

然而,最多可以有大约20个连接到系统1,大约10个连接到系统2。因此,为循环中的每个道具创建和销毁会话的简单想法(就像您在简单的Parallel.ForEach Task中所做的那样)将是非常昂贵的。相反,我希望共享连接,实际上,创建一个连接池。该池将在任务启动之前创建。当每个Task开始工作时,它基本上会等待,直到它可以从池中获得连接。一旦任务完成,连接将被释放,并且另一个Task可以获得它。在这种情况下,Scheduler的限制不仅仅是cpu;它也是到系统2的最大连接数。

的欲望

我在找方法。我不介意做一些工作来找出实施方案,但我需要最好的战略方法。

如何让任务循环使用有限数量的这些连接?或者我必须回到线程分配的旧风格,并且在线程完成其任务时手动传递释放的连接?某种互斥数组?如果是这样,任务将如何获取打开的连接?还是我走错方向了?

任何帮助将是非常感谢

受连接池限制的处理循环

我认为每个连接池的BlockingCollection将工作得很好。如果一个线程试图从空池中获取连接,则该线程将被阻塞,直到另一个线程将连接返回到该池。

您还应该将MaxDegreeOfParallelism设置为较大池的大小,以确保没有不必要的许多线程,它们中的大多数都在等待从池中获得连接。

这样,你的代码看起来就像这样了:
var connection = serviceAConnections.Take();
// use the connection
serviceAConnections.Add(connection);

但是更好的方法可能是在上面添加一个抽象级别:

using (var connectionHolder = serviceAConnections.Get())
{
   var connection = connectionHolder.Connection;
   // use the connection
}