I am working on a solution where I have a list of payloads which are needed to POSTED to one API endpoint.
The payload structure looks something like this and I have IList
of thousands of such payloads -
{
"Body": [{
"Payload": {
"emailaddress1": "test@email.com",
"initials": "RP",
"lastname": "Patil",
"firstname": "Patil"
},
"EntityName": "person",
"Url": "https://<someurl>/api/v1/persons",
"CollectionName": "persons",
"Method": "POST"
},
{
"Payload": {
"study_name": "Chemistry",
"teacher_name": "John Doe"
},
"EntityName": "study",
"Url": "https://<someurl>/api/v1/studies",
"CollectionName": "studies",
"Method": "POST"
}]
}
Now, the first object in this payload i.e. person
needs to be created first and when I receive the ID of that entity, I add that entity in second payload which is `study' after which the object becomes something like this -
{
"Payload": {
"person_id" : <newly_generated_id>
"study_name": "Chemistry",
"teacher_name": "John Doe"
},
"EntityName": "study",
"Url": "https://<someurl>/api/v1/studies",
"CollectionName": "studies",
"Method": "POST"
}
Currently I am doing it in old traditional way where I iterate through the IList
and use async await
. Wait for the response from first API call and then call the second one. However foreach
being single threaded, it is taking forever to create those many entities.
foreach(var payload in payloads)
{
var personObj = payload["Body"].Where(obj => obj["EntityName"].ToString().Equals("person")).FirstOrDefault();
var studyObj = payload["Body"].Where(obj => obj["EntityName"].ToString().Equals("study")).FirstOrDefault();
var personId = await _apiService.AddPerson(personObj);
if(personId != null){
studyObj["person_id"] = personId;
var studyId = await _apiService.AddStudy(studyObj);
//and more code.. this is just a sample code that demonstrates my implementation
}
}
This works well, however I am blocking all the threads till all thousands of persons and their studies have been created in our system. Can it be achieved by spawning single thread in each iteration? or similar implementation?
Can anyone guide me through better approach for this particular scenario? Something like Parallel.ForEach
?