使用 Parallel ForEach to POST in API 并单独处理每个响应

Using Parallel ForEach to POST in API and single Handle each Response

我想知道我生成的代码是否是好的做法并且不会产生泄漏,我有超过 7000 个对象参与者,我将单独推送它们并处理响应以将“外部”ID 保存在我们的数据库中.首先,我在列表 pPartcipant:

上使用 Parallel ForEach
Parallel.ForEach(pParticipant, participant =>
{
try
{
    //Create
    if (participant.id == null)
    {
        ExecuteRequestCreate(res, participant);
    }
    else
    {//Update
        ExecuteRequestUpdate(res, participant);
    }
}
catch (Exception ex)
{
    LogHelper.Log("Fail Parallel ", ex);
}
});

然后我做了一个经典的(不是异步请求),但是在我需要“处理”响应之后(在控制台中打印,以异步模式保存在文本文件中,并在我的数据库中更新)

    private async void ExecuteRequestCreate(Uri pRes, ParticipantDo pParticipant)
    {
        try
        {
            var request = SetRequest(pParticipant);

            //lTaskAll.Add(Task.Run(() => { ExecuteAll(request, pRes, pParticipant); }));
            //Task.Run(() => ExecuteAll(request, pRes, pParticipant));
            var result = RestExecute(request, pRes);
            await HandleResult(result, pParticipant);
            //lTaskHandle.Add(Task.Run(() => { HandleResult(result, pParticipant); }));
        }
        catch (Exception e)
        {
            lTaskLog.Add(LogHelper.Log(e.Message + " " + e.InnerException));
        }
    } 

我应该 运行 处理结果的新任务(如评论的那样)吗?它会提高性能吗? 在评论中你可以看到我创建了一个任务列表所以我可以在最后等待(任务日志是我写在文本文件中的所有任务):

       int nbtask = lTaskHandle.Count;
        try
        {
            Task.WhenAll(lTaskHandle).Wait();
            Task.WhenAll(lTaskLog).Wait();
        }

        catch (Exception ex)
        {
            LogHelper.Log("Fail on API calls tasks", ex);
        }

我没有任何界面它是一个控制台程序。

I would like to know if the code I produced is good practice

没有;你应该 avoid async void 并避免 Parallel 因为 async 工作。

这里有一个类似的顶层方法,使用异步并发代替Parallel:

var tasks = pParticipant
    .Select(participant =>
    {
      try
      {
        //Create
        if (participant.id == null)
        {
          await ExecuteRequestCreateAsync(res, participant);
        }
        else
        {//Update
          await ExecuteRequestUpdateAsync(res, participant);
        }
      }
      catch (Exception ex)
      {
        LogHelper.Log("Fail Parallel ", ex);
      }
    })
    .ToList();
await Task.WhenAll(tasks);

你的工作方法应该是async Task而不是async void:

private async Task ExecuteRequestCreateAsync(Uri pRes, ParticipantDo pParticipant)
{
  try
  {
    var request = SetRequest(pParticipant);
    var result = await RestExecuteAsync(request, pRes);
    await HandleResult(result, pParticipant);
  }
  catch (Exception e)
  {
    LogHelper.Log(e.Message + " " + e.InnerException);
  }
}