受连接池限制的处理循环
本文关键字:处理 循环 连接 | 更新日期: 2023-09-27 18:12:40
我在这里寻找一些战略帮助,因为我是TPL的新手。
情况我有一个应用程序,它在两个不同的LOB系统之间协调数据,这些系统彼此不通信。所以,它看起来有点像:
[ System 1 ] < ----- [ App ] ----- > [ System 2 ]
在处理过程中,应用程序执行以下任务:
- App创建到系统1的连接。此连接必须对web应用程序进行屏幕抓取,因此它使用a和System 2,验证每个都可用。
- App请求系统a的id列表
- 这个列表是逐项浏览的。处理列表:
- App向系统1请求数据。该系统不提供任何服务接口,因此应用程序使用WebRequest向系统1发送GET和POST请求。除了抓取网页数据外,还可以下载文件。
- 使用来自系统1的数据,App通过几个web服务调用向系统2提交数据。 可能有多个呼叫,也可能有文件上传。
循环中通常有成千上万个项目。这些项之间没有依赖关系,因此它们似乎是基于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
}