Reputation: 21
I am picking up looking at someone's code & need some advice over the use of Task.WhenAll()
.
We have the following simplified code:
Task<List<class1>> t1 = Task<List<class1>>.Factory.StartNew(LoadClass1);
Task<List<class2>> t2 = Task<List<class2>>.Factory.StartNew(LoadClass2);
Task<List<class3>> t3 = Task<List<class3>>.Factory.StartNew(LoadClass3);
var tasks = new Task[] { t1, t2, t3 };
The methods LoadClass1/2/3 are API calls to a service to get some data.
Task loadAllDataTask = Task.WhenAll(tasks);
try
{
await loadAllDataTask;
_class1Result = t1.Result;
_class2Result = t2.Result;
_class3Result = t3.Result;
}
catch (Exception)
{
if (loadAllDataTask.Exception != null)
{
throw loadAllDataTask.Exception;
}
}
The issue I am trying to resolve is when the API service is down. The tasks are awaited, and say one of the tasks endpoints t3
is down, it returns a 500 error. The task does not fail but returns a null value.
There is then a NullReference
exception fall over in the method LoadClass3 as it's just assigning the .Result
of the API call and returning it out.
Now in this example it's small but I have about 15 tasks that get going. Is there a way I can handle the exception of a null value for any task result within the Task.WhenAll
? Can I simply do something like for each task:
_class1Result = t1.Result ?? throw new Exception();
Wrap this round all the tasks?
Cheers for any advice
Upvotes: 1
Views: 720
Reputation: 2761
If result of the Task
is null
, and task is not failed - this is valid result. There is nothing wrong with this.
If for you null
is not an expected result, you can add checks for that inside function with task or even wrap task. Or even wrap your task inside another task that will perform the check.
Something like this:
Task<List<class1>> t1 = Task<List<class1>>.Factory.StartNew(NullCheck(LoadClass1));
...
async Task<T> NullCheck<T>(Task<T> task)
{
T taskResult = await task;
_ = taskResult ?? throw new InvalidOperationException("Result cannot be null");
return taskResult;
}
Upvotes: 1