5

I have the following scenario/requirement:

I have two tasks, task A and task B, which both return the same type of data. If task A, upon completion, has data in its result, I need to return the result of Task A - otherwise I return the result of task B.

I'm trying to performance optimize this for parallellism and I'm unsure if there's a better way than what I'm doing. This seems like a lot of code to do what I want.

var firstSuccessfulTask = await Task.WhenAny(taskA, taskB); if (firstSuccessfulTask != taskA) { await taskA; } if (taskA.Result != null) { return taskA.Result; } return await taskB; 
1
  • 3
    Why not just call await taskA first and skip the Task.WhenAny call? Commented Oct 10, 2017 at 18:09

1 Answer 1

12

Just write the code just the way your requirements read. return the result of A, unless it's null, in which case, return the result of B.

return await taskA ?? await taskB; 
Sign up to request clarification or add additional context in comments.

7 Comments

Wouldn't that not start the execution of taskB until taskA has completed, effectively making them serial and not parallel?
@PaulGelardi If taskB is actually a property that starts the task when you call that expression, then yes. If it's a local/field that has an already started task, then no. Given the naming convention, and the fact that you use taskA repeatedly (and thus clearly aren't creating new tasks each time you use it, because if you were the code wouldn't work at all) it makes it pretty clear that they're both variables, not expressions that compute new tasks. In the event that they really are expressions that compute new tasks, you'll need to store it in a local variable first, then do this.
That makes sense. I wasn't aware the taskB started executing as soon as I called the async method - I thought it didn't start until something was waiting for, or awaiting it.
@PaulGelardi await just "waits" for it to finish, its not called astart after all ;). But seriously, if you try to await a Task that represents a thread that has not been started (via calling new Task(...) instead of using the more correct Task.Run(...)) the await will never return until the thread is started somewhere else and then completes.
@PaulGelardi: Remember, await does not create asynchrony. It describes a restriction on a control flow involving existing asynchronous tasks. The restriction is the code which follows an await does not execute until after the task has completed.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.