Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return either an in-memory (cached) collection, or a task from an async await response

I have a scenario where my service class communicates to an API and populates a list. This method is

 public async Task<List<T>> Foo()

and in this method I am doing an async await to retrieve data from the API and deserialize to a list.

The thing is, I'd like to do something like this:

if (list is cached in memory)
   //serve data from the in memory list
else
   //await get data from the API

But the return type in the first part of the if statement is List<T> whereas the return type of the second part is Task<List<T>>

How can I do this? Can I just have my in-memory list be a Task? (Maybe I can wrap the List in a task)?

Thank you all!

like image 992
NullHypothesis Avatar asked Dec 23 '22 17:12

NullHypothesis


1 Answers

I'm not going into technical details here, but think about await as unwrapping a Task<T> into T and an async method as wrapping its return value T into Task<T>.

So if your method signature is like you asked

public async Task<List<T>> Foo()

Then your return value is different from your comment:

GetDataFromApi(); // results in Task<List<T>>
await GetDataFromApi(); // results in List<T>

So anyway, the return statement of an async Task<List<T>> expects List<T> and not Task<List<T>>

public async Task<List<T>> Foo()
{
    if (list is cached in memory)
        return list; //serve data from the in memory list
    else
        return await GetDataFromApi(); //await get data from the API
}

In case you don't use async await, you can wrap the result in a finished task:

public Task<List<T>> Foo()
{
    if (list is cached in memory)
        return Task.FromResult(list); //serve data from the in memory list
    else
        return GetDataFromApi(); //await get data from the API
}

Note both, async and await are removed in this second sample.

like image 163
grek40 Avatar answered Jan 11 '23 23:01

grek40