SW Dog
SW Dog

Reputation: 187

Does await Task.FromResult give any benefit?

I’ve worked on a baseline with code in this this form:

Var result = await Task.FromResult(_someObject.SomeNonAsyncMethod(someParameterObject));

From what I understand about Task.FromResult, this is simply packaging an object into a result form, not packaging a method into a task for asynchronous execution. Therefor the operations are adding extra overhead without any benefit.

Is this understanding correct?

Is this use of await doing anything useful in terms of performance?

Should await Task.FromResult ever be used in this way? (considering this line used alone - not implementing an interface or in a test, ect.)

Thanks in advance for any insight!

Upvotes: 5

Views: 4475

Answers (2)

Harald Coppoolse
Harald Coppoolse

Reputation: 30464

Sometimes you have to implement an interface, or override an abstract virtual function that is declared async, but there is no async function to call.

For instance, I have a method in an interface that fetches a person:

async Task<Person> FetchPersonAsync(int);

If you would want to fetch the person from some slow input, like from a database, or from the internet, or a file, then it would be meaningful to use the async function for this. However, if you have to read it from a local dictionary, for instance to mock in a unit test, then you don't have any async function to await for.

In cases there is no async function for you to await for, but you MUST implement the async function, use the FromResult:

async Task<Person> FetchPerson(int id)
{
    return await Task.FromResult<Person>(this.myPersonPictionary[id]);
}

For performance reasons, I would only do this if you really need too implement such a function, and you have nothing to await for.

Upvotes: 0

Ben Voigt
Ben Voigt

Reputation: 283684

There's no use for having both halves in the same line of code like that. However, it's useful for a function to package up its synchronous result in a Task in order to conform to an interface.

In some cases, a function may even have both synchronous and asynchronous execution. For example, there may be a synchronous lookup in a fast local cache, and on cache misses, a slow network operation. A function like this has to have a Task return type, which means the synchronous exits need to construct a Task from the already-known result.

Upvotes: 6

Related Questions