My requirement is to asynchronously process images for each request and once all the requests' images are processed, they are to be zipped. So for that i need to wait till all the images are processed.
Using a for loop for each item in my list to asynchronously call the method of the second API. However i need to wait for all the calls to the 2nd APIs method to execute before moving on to the next line in the code.
1st API:
public async void SegregateRecordsByRequestAndMerge(List<ClassB> listCDF, List<ClassA> records, string filePath)
{
List<ClassA> RequestList = records.GroupBy(x => x.RequestId)
.Select(g => g.First())
.ToList();
Task[] taskList = new Task[RequestList.Count];
for (int i = 0; i < RequestList.Count; i++) // reqList in RequestList)
{
ClassA reqList = new ClassA();
reqList = RequestList[i];
List < ClassA> recordsByRequest = records.Where(x => x.RequestId == reqList.RequestId).ToList();
ModelA serviceInput = new ModelA();
serviceInput.ClassBProperty = listCDF;
serviceInput.ClassAProperty = recordsByRequest;
taskList[i] = (Task.Factory.StartNew(() => ProcessImages(serviceInput, "myroute/processimage")));
}
Task.WaitAll(taskList, 600000);
}
This is how the service call is made
public void ProcessImages(CodingRecordAndCDFModel myServiceInput, string resource)
{
var client = new ServiceClient(BaseUrl)
{
Resource = resource
};
client.Post(JsonConvert.SerializeObject(myServiceInput).ToString());
}
2nd API(Image Processor) :
[HttpPost, Route("myroute/processimage"), ResponseType(typeof(string))]
public void GeneratePDFs([FromBody] string pdfServiceInput) {
if (!ModelState.IsValid) {
throw new Exception();
}
ModelA myServiceModel = new ModelA();
myServiceModel = JsonConvert.DeserializeObject <ModelA> (pdfServiceInput);
//// Logic to Process images
}
The problem i am facing is that, even though i am using WaitAll() a task cancelled exception is thrown. The control comes back to the 1st API before the method in the 2nd API is even completely executed.
I tried multiple ways, like using Parallel.ForEach(), Task.Whenall(), Task.Delay, TaskCreationOptions.LongRunning but none of them work... all of them throw the exception that the task got cancelled.
I need the control to wait till all the calls to the 2nd API return back to the 1st API and then do some other logic.
Can someone suggest what should be done? or any better way to handle this requirement?
Edit 1:
I think the problem is that i am trying to call a method asychronously, which will create 2 different async method calls... and since i am using the await or waitall on each async method, the moment the 1st call's execution is done the control returns to the 1st API even though there is another thread running in the 2nd API.
If there is a way to await a for loop or to wait till all the individual async calls are returned then that would be the soulution.