简体   繁体   English

Task.Run在for循环中

[英]Task.Run in a for loop

I have a for loop inside of which 我有一个for循环

First : I want to compute the SQL required to run 第一:我想计算运行所需的SQL

Second : Run the SQL asynchronously without waiting for them individually to finish in a loop 第二步:异步运行SQL,无需单独等待它们循环完成

My code looks like: 我的代码看起来像:

for (
        int i = 0;
        i < gm.ListGroupMembershipUploadDetailsInput.GroupMembershipUploadInputList.Count;
        i++)
{
     // Compute
     SQL.Upload.UploadDetails.insertGroupMembershipRecords(
         gm.ListGroupMembershipUploadDetailsInput.GroupMembershipUploadInputList[i],max_seq_key++,max_unit_key++,
         out strSPQuery,
         out listParam);

     //Run the out SPQuery async
     Task.Run(() => rep.ExecuteStoredProcedureInputTypeAsync(strSPQuery, listParam));
}

The insertGroupMembershipRecords method in a separate DAL class looks like : 单独的DAL类中的insertGroupMembershipRecords方法如下所示:

public static GroupMembershipUploadInput insertGroupMembershipRecords(GroupMembershipUploadInput gm, List<ChapterUploadFileDetailsHelper> ch, long max_seq_key, long max_unit_key, out string strSPQuery, out List<object> parameters)
{
    GroupMembershipUploadInput gmHelper = new GroupMembershipUploadInput();
    gmHelper = gm;
    int com_unit_key = -1;
    foreach(var item in com_unit_key_lst){
        if (item.nk_ecode == gm.nk_ecode)
            com_unit_key = item.unit_key;
    }

    int intNumberOfInputParameters = 42;
    List<string> listOutputParameters = new List<string> { "o_outputMessage" };
    strSPQuery = SPHelper.createSPQuery("dw_stuart_macs.strx_inst_cnst_grp_mbrshp", intNumberOfInputParameters, listOutputParameters);
    var ParamObjects = new List<object>();

    ParamObjects.Add(SPHelper.createTdParameter("i_seq_key", max_seq_key, "IN", TdType.BigInt, 10));
    ParamObjects.Add(SPHelper.createTdParameter("i_chpt_cd", "S" + gm.appl_src_cd.Substring(1), "IN", TdType.VarChar, 4));
    ParamObjects.Add(SPHelper.createTdParameter("i_nk_ecode", gm.nk_ecode, "IN", TdType.Char, 5)); 

    // rest of the method
   }

But in case of list Count of 2k which I tried, 但是在我尝试的list Count 2k的情况下,

It did not insert 2k records in DB but only 1. 它没有在DB中插入2k记录但只有1。

Why this does not insert all the records the input list has ? 为什么这不插入输入列表的所有记录?

What am I missing ? 我错过了什么?

Task.Run in a for loop Task.Run在for循环中

Even though this is not the question, the title itself is what I'm going to address. 即使这不是问题,标题本身也是我要解决的问题。 For CPU bound operations you could use Parallel.For or Parallel.ForEach , but since we are IO bound (ie; database calls) we should rethink this approach. 对于CPU绑定操作,您可以使用Parallel.ForParallel.ForEach ,但由于我们是IO绑定(即;数据库调用),我们应该重新考虑这种方法。

The obvious answer here is to create a list of tasks that represent the asynchronous operations and then await them using the Task.WhenAll API like this: 这里显而易见的答案是创建一个代表异步操作的任务列表,然后使用Task.WhenAll API等待它们,如下所示:

public async Task InvokeAllTheSqlAsync()
{
    var list = gm.ListGroupMembershipUploadDetailsInput.GroupMembershipUploadInputList;

    var tasks = Enumerable.Range(0, list.Count).Select(i =>
    {
        var value = list[i];
        string strSPQuery;
        List<SqlParameter> listParam;
        SQL.Upload.UploadDetails.insertGroupMembershipRecords(
            value, 
            max_seq_key++,
            max_unit_key++,
            out strSPQuery,
            out listParam
        );

        return rep.ExecuteStoredProcedureInputTypeAsync(strSPQuery, listParam);
    });

    await Task.WhenAll(tasks);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM