Default Initialize Task<T>

Viewed 237

I have a bunch of async tasks that may or may not be run based on the results of other expressions. Howerever, I still want to be able to await them all, but I can't do this since some will not be initialized. How can I default initialize a Task? For example:

        Task<string> ownerTask;
        if(fields.Select(x => x.Name == "owner").Any())
        {
            ownerTask = _repo.GetOwnerIdFromIssueId(issueId);
        }

        await Task.WhenAll(ownerTask, anothertask, anothertask, etc);

In this example, "ownerTask" may or may not actually have a task associated with it depending on the result of the if statement, but I don't want to have to block my thread by awaiting the task inside of the if.

Thanks!

3 Answers

Well, you could use a completed task:

Task<string> ownerTask = Task.FromResult("");

Alternatively, you could keep a list of the tasks you actually want to wait for, and only add "real" tasks to that list.

How can I default initialize a Task?

Task.Complete is a task that's completed with no result, and Task.FromResult() is a task that's completed with a result. So you probably want something like:

var ownerTask = fields.Any(x => x.Name == "owner") 
    ? _repo.GetOwnerIdFromIssueId(issueId) 
    : Task.FromResult((string)null);

But really, you shouldn't even be creating and/or awaiting this task if you know you don't need to. A much better pattern would be something like:

var tasks = new List<Task<string>>();

if(fields.Any(x => x.Name == "owner"))
    tasks.Add(_repo.GetOwnerIdFromIssueId(issueId));
// add the others

await Task.WhenAll(tasks);

You should use the Task.WhenAll(IEnumerable<Task> tasks); overload, this way you can await variable count of tasks.

var tasks = new List<Task>();

if(fields.Select(x => x.Name == "owner").Any())
{
    tasks.Add(_repo.GetOwnerIdFromIssueId(issueId));
}

tasks.Add(anothertask);

// You could even check if any task is added to the list
// this way you will skip an await.
if(tasks.Count > 0)
    await Task.WhenAll(tasks);
Related