I have a process which retrieves from the DB a list of rows, and per each row must execute a list of long-running operations:
- Upload a file to a FTP server
- Check every 1 minute if a particular file (that is created based on the uploaded in 1) is available in such FTP server
- Download the file found in step 2, once available
- Save content of the file downloaded in the DB
I've implemented a method which does all these steps following the sequence mentioned above: I want to call that method multiple times in parallel (asynchronously): The amount of times to call it will depend of the number of rows retrieved at the beginning of the workflow.
An extraction of the main method follows:
List<Model> ftpModels = _service.CreateFtpModel(rowsFromDB); List<Task> asyncTasks = new List<Task>(); ftpModels.AsParallel().ForAll(p => { asyncTasks.Add(DoStepsAsync(p)); }); // Wait for all the tasks to finish. await Task.WhenAll(asyncTasks.Where(p => p != null)); First, a list of Models is created based on the rows retrieved from the DB, then an empty list of Tasks is created and then iterates through the models created to execute the async method "DoStepsAsync" which retrieves a task to insert into the asyncTasks list. Finally, it calls Tasks.WhellAll for all the tasks.
This approach is working properly usually, but I happened to find that sometimes (randomly so thread related issue) the next exception is thrown on the WhenAll method:
System.AggregateException: One or more errors occurred. ---> System.ArgumentException: The tasks argument included a null value.
Which clearly indicates me that any of the tasks above returned null (instead of a task) while they were being executed. Then I read the logs I'm writing but I did not find any exception anywhere, just the flow interrupted out of the blue falling next into the System.AggregateException
I was googling and reading a lot, and this issue happens when:
At least one of the Task instances was canceled. If a task was canceled, the AggregateException exception contains an OperationCanceledException exception in its AggregateException.InnerExceptions collection. -or- An exception was thrown during the execution of at least one of the Task instances.
But no exception was thrown as I have try-catch blocks implemented accordingly. Therefore, i don't know what the hell is happening.
Any suggestion?
Just to give more info about what happens within the DoStepsAsync() method, there are asynchronous calls to the FTP client (thread safe), writing logs and stuff like that. What really surprises me is that no exception is caught anywhere even with all the catch blocks mentioned above.
Any suggestion really appreciated.
asyncTasks.Where(p => p != null))is not the samepas that above it, it's aTaskwhich is likely never null. Did you you mean to filter the nullpbefore theForEach?Selectto produce theasyncTaskscollection instead of the mutatingForEachsince the only command running inside theForEachis aList<T>.Add