Асинхронный вызов пакета SSIS
-
03-07-2019 - |
Вопрос
Я вызываю пакет SSIS, используя LoadPackage(...).
Можно ли сделать этот вызов асинхронным?
Решение
Да, используйте асинхронный делегат, как показано здесь:
Другие советы
Если вы просто хотите, чтобы он запускался в фоновом режиме, то да, вы можете либо запустить поток, либо вызвать какой-нибудь T-SQL для динамического создания задания (и впоследствии снова удалить его).Если вы хотите запустить его асинхронно и хотите получить обратный вызов, когда это будет сделано, то я думаю, что вам, к сожалению, не повезло.
Вы спрашиваете, 1) законно ли вызывать LoadPackage в фоновом потоке или 2) возможно ли это.Для # 1 я не могу дать окончательного ответа, потому что я не использую фреймворк SSIS.
Однако #2 (при условии, что # 1 истинно) определенно выполнимо.ИМХО, вам лучше использовать существующий фреймворк, в котором есть API, предназначенные для вызова async API и ожидания результатов.Например, для расширения Parellel от 08 июня CTP подойдет следующий код.
using System.Threading.Tasks;
...
var future = Future.Create(()=>LoadPackage); // Starts loading the package
// Do other stuff
var package = future.Value; // Wait for package load to complete and get the value
Я вызываю пакет SSIS из моего пользовательского интерфейса (WPF) с помощью асинхронного вызова службы WCF.Сервисный код - это:
public string ImportMarriageXML(bool isWakeUp, bool clearExistingMarriage)
{
try
{
var dts = new Microsoft.SqlServer.Dts.Runtime.Application();
using (var package = dts.LoadFromSqlServer(
ServiceSettings.Settings.SSIS.ImportMarriages,
ServiceSettings.Settings.SSIS.ServerIP,
ServiceSettings.Settings.SSIS.UserID,
ServiceSettings.Settings.SSIS.Password,
null))
{
package.InteractiveMode = false;
package.Connections["DB.STAGING"].ConnectionString = String.Format("{0};Provider={1};", DBSettings.ConnectionString(Core.Database.Staging), ServiceSettings.Settings.SSIS.Provider);
var variables = package.Variables;
variables["IsWakeUp"].Value = isWakeUp;
variables["ClearExistingMarriage"].Value = clearExistingMarriage;
variables["XmlDirectory"].Value = ServiceSettings.Settings.SSIS.Properties.XmlDirectory;
if (package.Execute() == DTSExecResult.Failure)
{
// HACK: Need to refactor this at some point. Will do for now.
var errors = new System.Text.StringBuilder();
foreach (var error in package.Errors)
errors.AppendFormat("SubComponent: {0}; Description: {1}{2}", error.SubComponent, error.Description, Environment.NewLine);
throw new ApplicationException(errors.ToString());
}
return package.Connections["Text Logging"].ConnectionString;
}
}
}
И (часть) клиентского кода выглядит следующим образом:
private void InvokeLoadMarriages()
{
integrationServicesServiceClient.BeginImportMarriageXML(false, OnEndImportMarriageXML, null);
}
private void OnEndImportMarriageXML(IAsyncResult asyncResult)
{
view.InvokeDisplayResults(integrationServicesServiceClient.EndImportMarriageXML(asyncResult));
}
Где BeginImportMarriageXML и EndImportMarriageXML - это сгенерированные асинхронные операции в классе прокси.