Проблема с асинхронным ожиданием при вызове API в цикле в задаче сценария SSIS
Я вызываю веб-API c# с помощью задачи сценария SSIS. Требование состоит в том, чтобы выбрать данные запроса из таблицы, преобразовать каждую строку в запрос, вызвать API для каждого запроса и сохранить ответ в таблице.
Я обхожу все строки таблицы и вызываю API внутри цикла для одного запроса (строки) за один раз. Весь процесс, если я вызываю API синхронно, занимает много времени. Поэтому я начал вызывать API асинхронно, используя await и async.
Проблема в том, что API вызывается всего несколько раз (в основном только 15-16 раз). Однако цикл должен вызывать API всего 100 раз.
В конце цикла я использую whenAll, чтобы проверить, получил ли я ответы на все запросы, но это не помогает и по-прежнему дает мне только 15-17 ответов каждый раз. Неудачи нет нигде.
Если я использую спящий режим или жду каждой задачи (что то же самое, что синхронный вызов API), API вызывается для всех 100 записей.
public async Task<List<MyResponse>> demoAsync(DataSet sourceDataTable, string[] accessTokeninfo, string connectionString, string DestTableName, string ClientId, string ClientSecret, string GrantType, string EndPoint, string MRMEndPoint, string OPSErrortableName, string BatchID) { List<MyResponse> finalResp = new List<MyResponse>(); DataTable dtResponseOPS = GetDestTable(DestTableName, connectionString); // get Error Response Meta data Logging table MRM.OPSResponseMeta DataTable dtResponseMetaOPS = GetDestTable("MRM.OPSResponseMeta", connectionString); DBUtility utility = new DBUtility(); List<Task<MyResponse>> queryTasks = new List<Task<MyResponse>>(); foreach (DataRow rw in sourceDataTable.Tables[0].Rows) { MyResponse response = new MyResponse(); ConsumeMRMAPI obj = new ConsumeMRMAPI(); OPSRequestModel requestData = new OPSRequestModel(); requestData = CreateItemFromRow<OPSRequestModel>(rw); string filtercriteria = ""; reqCounter = IsTimeExpired(); if (reqCounter > 65) { Thread.Sleep(Convert.ToInt32(tm.Interval)); } if (DateTime.Now < tokenExpirytime) { Task<MyResponse> task = obj.GetXMLObject(MRMEndPoint + filtercriteria, accessTokeninfo[0], requestData); queryTasks.Add(task); } else { accessTokeninfo = GetAccessToken(ClientId, ClientSecret, GrantType, EndPoint); tokenExpirytime = DateTime.Now.AddSeconds(Convert.ToInt32(accessTokeninfo[1]) - 300); //response = obj.GetXMLObject(MRMEndPoint + filtercriteria, accessTokeninfo[0], requestData); if (!string.IsNullOrEmpty(response.validResponse)) { // destDataTable.Rows.Add(0, mpin, npi, taxId, fname, lname, null, null, null, null, response.validResponse, null, null, null, null, null, null, null, "1", BatchID); } } reqCounter++; if (dtResponseOPS.Rows.Count >= 100) { //parameters = SetupSPParameters(sourceDataTable,EnrichSystemID,BatchID); //resultCode = new DAHelper(connectionString).ExecuteSP(ProcedureName, parameters.ToArray(), out resultData, out errorCode, out errorNumber, out errorMessage); utility.DoInsertFileInfo(dtResponseOPS, DestTableName, connectionString); dtResponseOPS.Clear(); } } await System.Threading.Tasks.Task.WhenAll(queryTasks); foreach (Task<MyResponse> task in queryTasks) { finalResp.Add(task.Result); } return finalResp; } }
Что я уже пробовал:
Я уже пробовал ждать каждое задание
Task<mrmresponse> task = obj.GetXMLObject(MRMEndPoint + filtercriteria, accessTokeninfo[0], requestData);
задач.ждать();
queryTasks.Добавить(задача);
Это помогает, и я могу вызвать API для всех 100 запросов, но это не тот способ, который я знаю.
Richard Deeming
Это не решение, но если вы можете изменить тип возвращаемого значения метода на Task<IList<MyResponse>>
, то вы можете заменить этот последний цикл на:
return await Task.WhenAll(queryTasks);
Задача.WhenAll[^] возвращает массив результатов ожидаемых задач.
Richard Deeming
Вы упомянули, что вызываете это через SSIS - вы уверены, что он поддерживает методы, возвращающие a Task
? Это звучит так, как будто он не ждет завершения задачи.
gouravkaila91
Я не уверен, но SSIS script task использует C# 5.0 внутренне, так что это должно поддерживаться.