C# 创建源于队列(数据库表)的SSIS作业的调用程序

C# 创建源于队列(数据库表)的SSIS作业的调用程序,c#,.net,multithreading,asynchronous,.net-3.5,C#,.net,Multithreading,Asynchronous,.net 3.5,前言:我是一名DBA,了解一些C#,但在这方面还远远不是专家。我的任务是创建SSIS作业的调用程序,该调用程序来自数据库表中的队列。我的想法是,将未启动的任务取为top X(作业运行时的动态值,来源于数据库表),并并行运行它们。要求任务彼此并行运行。虽然从SSIS中的包运行包很容易,但我不相信有办法(仔细研究后)像这样并行运行它们 我决定通过创建一个SSIS作业作为调用程序来实现这一点。它收集要运行的任务(及其详细信息和参数),然后使用脚本任务调用C#assembly,SsisHelper(也是

前言:我是一名DBA,了解一些C#,但在这方面还远远不是专家。我的任务是创建SSIS作业的调用程序,该调用程序来自数据库表中的队列。我的想法是,将未启动的任务取为top X(作业运行时的动态值,来源于数据库表),并并行运行它们。要求任务彼此并行运行。虽然从SSIS中的包运行包很容易,但我不相信有办法(仔细研究后)像这样并行运行它们

我决定通过创建一个SSIS作业作为调用程序来实现这一点。它收集要运行的任务(及其详细信息和参数),然后使用脚本任务调用C#assembly,SsisHelper(也是由我编写的),它使用BackgroundWorkers并行运行任务。现在一切都好了

然而,我最近得知,这种方法并不完全满足要求。如果第一个(X-1)任务在一分钟内完成,但最后一个任务需要一个小时才能运行,我们不希望在用新任务补充队列中的其他插槽之前等待。但是,我们不一定要异步运行整个调用程序任务(至少不是在当前状态下),因为我们可能最终运行(X+1)个任务,这同样糟糕

我的想法是对SsisHelper进行异步调用,但在此之前,请尝试查看程序集是否仍处于活动状态(即,它仍在等待最后一两个作业完成),然后重新使用它。然后,在SsisHelper中,我将有一个运行任务的静态计数,以确保它不会超过X。虽然第二部分看起来很简单,但我不知道是否有可能选择这样一个运行的.NET进程。我当然愿意接受其他选择,但我无法改变队列最初需要从SSI进行管理的事实


编辑-这必须在.NET 3.5中完成。

使用具有边界容量的BlockingCollection


如果文件组位于同一写入头上,则并行文件组没有帮助

假设我理解您的问题,就不需要复杂的高质量的C#和多线程处理

我假设您的队列有如下概念

Task | Start Time | Finish Time | Uniqueifier
SSIS |            |             | 1
WCF  |            |             | 10000000
考虑这个SSIS包。它是调用程序

启动此包时,您将指示要运行的队列中的活动项目数。根据SSIS的版本,它可能是一个
/SET
或一个包参数

第一步是查看队列中是否有工作。初始化一些SSIS变量以指示是,还有工作要做

这将导致For循环,而不是Foreach循环。For循环将循环,直到变量指示没有工作要做

在For循环中,我们查询队列以查看有多少活动进程正在运行。基本上,计算有多少开始时间没有结束时间。如果该计数小于我们的目标线程数,我们将采用左边的路径。如果它大于或等于,那么我们就选择正确的道路

左路 左边的路径阐述了开始新事物的概念。第一步是从队列中获取项目。这将为您提供有关需要执行的任务的足够信息和任务id,以便您可以将该引用传递给实际的工作人员。作为获取此引用的一部分,我会将该过程标记为正在进行(开始时间=当前时间戳)。也许你更愿意把它转移到过程真正开始的时候。这是一个设计决策,取决于您的具体需求

左边路径中的第二步是实际运行这个东西。我有一个执行流程任务的占位符。也许这不是正确的做法。也许你需要一个脚本任务。其实这并不重要,概念是您需要启动一个异步进程。有比答案所允许的更多的方法来解决运行ansyc流程的细节问题。关键的一点是传递对任务的引用,这样当子流程完成时,它会将任务标记为完成(这里通过设置完成时间)

正道 这只是一个睡眠任务。当我们所有的队列都处于活动状态时,它会加速。睡一秒钟,睡一分钟,睡一小时。这完全取决于你估计的时间范围。您希望在不降低处理下一个队列项目的响应时间的情况下最小化观察者效应

工作任务 这将是您的工作任务。作为子SSIS包实现,但我并不真正关心它是什么。它只需要

  • 做任务
  • 向队列报告它已完成其任务

  • 是什么让您能够确保并行执行X任务比串行运行更快?数据库有固定的cpu、内存和磁盘头。如果一个任务正在使用cpu,而另一个任务正在使用cpu,那么理论上是的,您可以得到一些真正的并行处理。实际上,大多数情况下都是磁盘争用,为了让它集中精力,速度更快。任务必须并行运行。重申一下:您有一个队列。您希望启动N个SSI实例,每个实例从队列中获取一个项目。队列项确定运行的包。是吗?你看过SSIS团队如何在30分钟内加载1 Tb的报告吗?这不仅仅是速度问题。我知道可能有一项任务需要10分钟才能完成。当第一个任务试图完成时,我不能让一个完全无关的任务等待运行。这些任务必须能够并行运行。BlockingCollections是.NET 4.0+,对吗?很遗憾,我必须使用3.5。对不起。下一次,我将只发布带有简单答案的问题。简单答案和完整问题不一样。我简单的回答是无效的,因为问题不完整。你有7个问题没有一个被接受的答案。你似乎只得到了不好的回答。啊,你的回答不具体