C# 在SSIS脚本任务的循环中调用API时出现异步等待问题

C# 在SSIS脚本任务的循环中调用API时出现异步等待问题,c#,asp.net-web-api,ssis,async-await,script-task,C#,Asp.net Web Api,Ssis,Async Await,Script Task,我正在使用SSIS脚本任务调用一个c#web API。需求是从表中提取请求数据,将每一行转换为请求,为每个请求调用API,并将响应存储在表中 我在表的所有行中循环,并在循环中一次调用一个请求(行)的API。如果我同步调用API,整个过程会花费很多时间。因此,我开始使用wait和async异步调用API 问题是API只被调用了几次(大部分只有15-16次)。但是,循环应该总共调用API 100次 在循环结束时,我使用whenAll检查我是否收到了所有请求的响应,但它没有帮助,每次只给我15-17个

我正在使用SSIS脚本任务调用一个c#web API。需求是从表中提取请求数据,将每一行转换为请求,为每个请求调用API,并将响应存储在表中

我在表的所有行中循环,并在循环中一次调用一个请求(行)的API。如果我同步调用API,整个过程会花费很多时间。因此,我开始使用wait和async异步调用API

问题是API只被调用了几次(大部分只有15-16次)。但是,循环应该总共调用API 100次

在循环结束时,我使用whenAll检查我是否收到了所有请求的响应,但它没有帮助,每次只给我15-17个响应。任何地方都没有失败

如果我使用睡眠或等待每个任务(这与同步调用API相同),则会为所有100条记录调用API

我已经试着等待每一项任务

Task<MRMResponse> task =  obj.GetXMLObject(MRMEndPoint + filtercriteria,
        accessTokeninfo[0], requestData);

task.wait();

queryTasks.Add(task);
Task Task=obj.GetXMLObject(MRMEndPoint+filtercriteria,
accessTokeninfo[0],requestData);
task.wait();
添加(任务);
这很有帮助,我可以为所有100个请求调用API,但这不是我所知道的方式

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;
    }
}
public async Task demoAsync(DataSet sourceDataTable、string[]accessTokeninfo、string connectionString、string DestTableName、string ClientId、string ClientSecret、string GrantType、string EndPoint、string OPSErrortableName、string BatchID)
{
List finalResp=新列表();
DataTable dtResponseOPS=GetDestTable(DestTableName,connectionString);
//获取错误响应元数据记录表MRM.OPSResponseMeta
DataTable dtResponseMetaOPS=GetDestTable(“MRM.OPSResponseMeta”,connectionString);
DBUtility=新的DBUtility();
列表查询任务=新列表();
foreach(sourceDataTable.Tables[0].Rows中的DataRow rw)
{
MyResponse=新的MyResponse();
ConsumerMRMAPI obj=新ConsumerMRMAPI();
OPSRequestModel requestData=新的OPSRequestModel();
requestData=CreateItemFromRow(rw);
字符串filtercriteria=“”;
reqCounter=IsTimeExpired();
如果(reqCounter>65)
{
线程睡眠(转换为32(tm.Interval));
}
if(DateTime.Now=100)
{
//参数=设置参数(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();
}
}
等待系统.Threading.Tasks.Task.WhenAll(查询任务);
foreach(查询任务中的任务)
{
最终添加(任务结果);
}
返回最终ESP;
}
}

Sidenote:你最好用
Task.Delay
替换
Thread.Sleep
,使其不阻塞。你说不是所有请求都被执行。是否
if(DateTime.Now
的计算结果为false,因此不会创建任何请求?这里有很多内容,其中很多内容没有显示,因此很难提供帮助。(什么是
ConsumerMapi
?为什么每次在循环中都创建一个新的?在
GetXMLObject
中会发生什么?)您最好将其简化为。很可能你自己会发现问题,如果不是这样,那么结果在寻求帮助时会更有用。@PeterBons-谢谢,会的@PeterBons-TokenExpiration不是问题,它的值设置得相当高。此外,这仅仅是100个请求,在同步中不应超过一分钟,而在异步调用中,我期望的时间更少。