使用 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);
}
}
我想知道我生成的代码是否是好的做法并且不会产生泄漏,我有超过 7000 个对象参与者,我将单独推送它们并处理响应以将“外部”ID 保存在我们的数据库中.首先,我在列表 pPartcipant:
上使用 Parallel ForEachParallel.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);
}
}