0

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

情况

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

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

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

  1. 应用程序创建到系统 1 的连接。此连接必须对 Web 应用程序进行屏幕抓取,因此它使用 a 和系统 2,验证每一个都可用。
  2. 应用程序从系统 A 请求 ID 列表。
  3. 此列表逐项运行。处理该列表:
    1. App向System 1请求数据。该系统不提供任何服务接口,因此App使用WebRequest对System 1进行GET和POST请求。除了抓取网页数据外,还可以下载文件。
    2. 使用来自 System 1 的数据,App 通过多个 Web 服务调用将数据提交给 System 2。可能会进行多次调用,并且可能会上传一个文件。

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

但是,最多可以有大约 20 个到系统 1 的连接和大约 10 个到系统 2 的连接。因此,为循环中的每个项目创建和销毁会话的简单想法(就像您可能在 simple 中所做的那样Parallel.ForEach Task)将是昂贵得令人望而却步。相反,我想共享连接,实际上是创建各种连接池。该池将在任务启动之前创建。当每个Task人开始工作时,它基本上会等到它可以从池中获得连接。一旦任务完成,连接就会被释放,另一个Task人可以得到它。在这种情况下,调度程序的限制不仅仅是 CPU;也是最大数与系统 2 的连接。

欲望

我正在寻找方法。我不介意做一些工作来弄清楚实施,但我需要最好的战略方法。

如何让任务循环与有限数量的这些连接一起工作?还是我必须回到旧的线程分配方式,在线程完成任务时手动传递释放的连接?某种互斥数组?如果是这样,任务将如何获取打开的连接?某种类型的并发包还是我走错了路?

任何帮助将不胜感激。

4

1 回答 1

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
}
于 2013-05-09T13:19:38.183 回答