0

Task<StandardResponse<bool>> qcTask;
Task<StandardResponse<bool>> ccTask;
Task<StandardResponse<bool>> cfTask;

qcTask = service.ProcessQuestionsAndComments(inputData);
if (StatusId == (int)STATUS.COMPLETED)
{
    ccTask = service.ProcessCompletedStatus(inputData);
    cfTask = service.ProcessCompletedFile(inputData);
}

await Task.WhenAll(qcTask, ccTask, cfTask).ConfigureAwait(false);

problem here is, in the last line I cant use ccTask, cfTask as they are not assigned.

I tried with using some default task in else, but its state always stays in Created. something like this

else
{
    ccTask = new Task<StandardResponse<bool>>(() => { return new StandardResponse<bool>() { Status = HttpStatusCode.OK }; });
    cfTask = new Task<StandardResponse<bool>>(() => { return new StandardResponse<bool>() { Status = HttpStatusCode.OK }; });
}

anyway I can handle this task conditionaly.

3 Answers3

1

You could put the tasks in a list, and only add the ccTask and cfTask if the status is completed. Then tell WhenAll to process the list, instead of individual variables. That way it won't matter how many there are, or whether they've been instantiated or not.

This should work:

var tasks = new List<Task<StandardResponse<bool>>>();
tasks.Add(service.ProcessQuestionsAndComments(inputData));

if (StatusId == (int)STATUS.COMPLETED)
{
    tasks.Add(service.ProcessCompletedStatus(inputData));
    tasks.Add(service.ProcessCompletedFile(inputData));
}

await Task.WhenAll(tasks).ConfigureAwait(false);

See also the documentation

ADyson
  • 57,178
  • 14
  • 51
  • 63
  • That was the option I had, but didnt useed it because hate to access result by index. Unless you have generic response handling, dont like to use list. But anyway, seems I dont have any other option for now. – Kiran Ramchandra Parab Mar 17 '23 at 10:39
  • @KiranRamchandraParab well you could also try [JonasH's suggestion](https://stackoverflow.com/a/75766157/5947043). But equally, you could use a Dictionary if you prefer to access the data via named keys rather than indexes. Dictionary [implements IEnumerable](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2?view=net-8.0) so you should still be able to pass it into WhenAll (see [here](https://stackoverflow.com/a/47867041/5947043) for similar example - uses WhenAny, but the signature is the same as for WhenAll). – ADyson Mar 17 '23 at 10:43
1

Just to add to ADyson's answer, OP has subsequently identified the need to interrogate the results of each of each of the tasks, and doesn't want to use assumptions about ordinal position in a list. In this case, a keyed Dictionary (e.g. by task name or other indicator) can be used to track the tasks after completion, e.g.

var myTasks = new Dictionary<string, Task<StandardResponse<bool>>>()
{
    ["qcTask"] = service.ProcessQuestionsAndComments(inputData)
};
if (StatusId == (int)STATUS.COMPLETED)
{
   myTasks["ccTask"] = service.ProcessCompletedStatus(inputData);
   myTasks["cfTask"] = service.ProcessCompletedFile(inputData);
}
await Task.WhenAll(myTasks.Values);

// ...work with myTasks["qcTask"].Result et al here. Note that you will need to be defensive about 
// access, since not all keys may be in the dictionary. `TryGetValue()` is probably a good fit.
StuartLC
  • 104,537
  • 17
  • 209
  • 285
1

Using a List<T> is a fine approach. The solution below is closer to what you were originally trying to achieve. What you actually want is a completed task, not a new Task; you should never use new Task (as described on my blog).

Task<StandardResponse<bool>> qcTask;
Task<StandardResponse<bool>> ccTask;
Task<StandardResponse<bool>> cfTask;

StandardResponse<bool> notRunValue = null;

qcTask = service.ProcessQuestionsAndComments(inputData);
if (StatusId == (int)STATUS.COMPLETED)
{
  ccTask = service.ProcessCompletedStatus(inputData);
  cfTask = service.ProcessCompletedFile(inputData);
}
else
{
  ccTask = Task.FromResult(notRunValue);
  cfTask = Task.FromResult(notRunValue);
}

var results = await Task.WhenAll(qcTask, ccTask, cfTask).ConfigureAwait(false);
Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810