4
我的影片启动另一个SSIS包在的foreach容器的SSIS包;因为一旦它启动了所有必须启动的包,容器就报告完成,我需要一种方法让它等到所有“子”包完成。轮询SSIS执行状态
所以我实现了一个小的睡眠等待循环,基本上拉Execution
对象关SSISDB为ID的,我感兴趣的
我面临的问题,是一个总计0 Dts.Events.FireProgress
事件被解雇,如果我取消在do
循环的Dts.Events.FireInformation
呼叫,然后每一秒我得到一个消息报道说,23包仍在运行...除非我在SSISDB的活动操作检查窗口,我看到大部分已完成已经和3或4实际上是正在运行。
我在做什么错,为什么不会runningCount
包含实际运行执行次数?
using ssis = Microsoft.SqlServer.Management.IntegrationServices;
public void Main()
{
const string serverName = "REDACTED";
const string catalogName = "SSISDB";
var ssisConnectionString = $"Data Source={serverName};Initial Catalog=msdb;Integrated Security=SSPI;";
var ids = GetExecutionIDs(serverName);
var idCount = ids.Count();
var previousCount = -1;
var iterations = 0;
try
{
var fireAgain = true;
const int secondsToSleep = 1;
var sleepTime = TimeSpan.FromSeconds(secondsToSleep);
var maxIterations = TimeSpan.FromHours(1).TotalSeconds/sleepTime.TotalSeconds;
IDictionary<long, ssis.Operation.ServerOperationStatus> catalogExecutions;
using (var connection = new SqlConnection(ssisConnectionString))
{
var server = new ssis.IntegrationServices(connection);
var catalog = server.Catalogs[catalogName];
do
{
catalogExecutions = catalog.Executions
.Where(execution => ids.Contains(execution.Id))
.ToDictionary(execution => execution.Id, execution => execution.Status);
var runningCount = catalogExecutions.Count(kvp => kvp.Value == ssis.Operation.ServerOperationStatus.Running);
System.Threading.Thread.Sleep(sleepTime);
//Dts.Events.FireInformation(0, "ScriptMain", $"{runningCount} packages still running.", string.Empty, 0, ref fireAgain);
if (runningCount != previousCount)
{
previousCount = runningCount;
decimal completed = idCount - runningCount;
decimal percentCompleted = completed/idCount;
Dts.Events.FireProgress($"Waiting... {completed}/{idCount} completed", Convert.ToInt32(100 * percentCompleted), 0, 0, "", ref fireAgain);
}
iterations++;
if (iterations >= maxIterations)
{
Dts.Events.FireWarning(0, "ScriptMain", $"Timeout expired, requesting cancellation.", string.Empty, 0);
Dts.Events.FireQueryCancel();
Dts.TaskResult = (int)Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Canceled;
return;
}
}
while (catalogExecutions.Any(kvp => kvp.Value == ssis.Operation.ServerOperationStatus.Running));
}
}
catch (Exception exception)
{
if (exception.InnerException != null)
{
Dts.Events.FireError(0, "ScriptMain", exception.InnerException.ToString(), string.Empty, 0);
}
Dts.Events.FireError(0, "ScriptMain", exception.ToString(), string.Empty, 0);
Dts.Log(exception.ToString(), 0, new byte[0]);
Dts.TaskResult = (int)ScriptResults.Failure;
return;
}
Dts.TaskResult = (int)ScriptResults.Success;
}
GetExecutionIDs
函数只是从我的元数据库中返回子包的所有执行ID。
我没有用'C#'SSIS的,但你不能'你可以在SSDT execute'在'C#'包?这样你在继续处理之前得到一个结果。 – NickyvV
@NickyvV foreach循环迭代是行的元数据,以确定如何处理参数封装 - 我正在同一个包20+情况下,在一个循环,我需要他们同时运行(这部分作品)。问题是,如果我什么都不做,那么“主”包会在“子”包完成运行之前报告完成,我不能这样做。上面是一个*脚本任务*,它跟在foreach容器之后,基本上等待所有“子”包完成。我不能将'execute'作为阻塞调用,因为我需要它们并发。 –
此外,由于某种原因,我不能在任何地方该脚本打破 - 我的意思是我*可*把断点,但他们从来不打*尽管显示在脚本任务框的红点*的SSIS控制流。 –