处理循环受连接池限制(?)

时间:2013-05-09 03:08:24

标签: c# task-parallel-library

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

情况

我有一个应用程序可以协调2个不同的LOB系统之间的数据,这些LOB系统之间没有相互通信。所以,它看起来有点像:

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

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

  1. App创建与System 1的连接。此连接必须屏幕抓取Web应用程序,因此它使用a和System 2,验证每个应用程序是否可用。
  2. 应用程序请求系统A中的ID列表。
  3. 此列表逐项运行。处理该清单:
    1. 应用程序从系统1请求数据。此系统不提供任何服务接口,因此应用程序使用WebRequest同时向系统1发出GET和POST请求。除了抓取网页数据外,还可以下载文件。
    2. 使用来自系统1的数据,App通过多个Web服务调用将数据提交到系统2。可能会进行多次调用,并且可能会上传文件。
  4. 循环中通常有成千上万的项目。这些项目之间没有依赖关系,因此它们似乎是基于Task的处理的良好候选者。

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

    欲望

    我正在寻找这种方法。我不介意做出实现的工作,但我需要最好的战略方法。

    如何让任务循环使用有限数量的这些连接?或者我是否必须回到旧式的线程分配,并在线程完成任务时手动传递释放的连接?某种互斥阵列?如果是这样,任务将如何获取打开的连接?某种类型的并发包或我只是走错路?

    任何帮助都会 非常 赞赏。

1 个答案:

答案 0 :(得分:0)

我认为每个连接池的BlockingCollection都能正常运行。如果某个线程试图从空池中获取连接,该线程将被阻塞,直到另一个线程返回到该池的连接。

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

这样,您的代码可能如下所示:

var connection = serviceAConnections.Take();

// use the connection

serviceAConnections.Add(connection);

但更好的方法可能是增加一个抽象层次:

using (var connectionHolder = serviceAConnections.Get())
{
   var connection = connectionHolder.Connection;

   // use the connection
}