gouravkaila91 Ответов: 0

Проблема с асинхронным ожиданием при вызове 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 внутренне, так что это должно поддерживаться.

0 Ответов