-5

I need to write a function that returns with a signature just like the one below.

public async Task<IEnumerable<RouteData>> GetAll()
{
   return await _dbContext.RouteData.ToListAsync();
}

The above works because EntityFramework gives me RouteData which I can call the extension method ToListAsync on.

However, I am creating a list statically that I return from GetAll() that I want to return as async. I've tried Task(() => GetAll()) with no luck. Here is my method that returns correctly without async

public IEnumerable<RouteData> GetAll()
{
    List <RouteData> routeDataList = GetRoutesAll();
    return routeDataList;
}

My question is, what is the code that I would use to return from this:

public async Task<IEnumerable<RouteData>> GetAll()
{
   return await GetRoutesAll();  // THIS DOESN'T WORK
}

   
Pete
  • 3,111
  • 6
  • 20
  • 43
  • 5
    If `GetRoutesAll()` is a synchronous method, why do you want the signature of `GetAll()` to be async? There's nothing to await. You could start a task using `return await Task.Run(() => GetRoutesAll());` but whether or not that's the proper way depends on the implementation of `GetRoutesAll()` which you didn't include in the question. – 41686d6564 stands w. Palestine Aug 14 '20 at 01:54
  • 3
    Very unclear what you want to achieve - "that I want to return as async" - Do you want "create async wrapper around synchronous method" (usually bad idea, but who's going to stop you), "keep `GetRoutesAll` synchronous, but make `async Task> GetAll()` compile without errors/warnings", "have `GetAll` method that can be await'ed later", something totally different? (Showing signature of `GetRoutesAll` and desired usage of `GetAll` may help...) – Alexei Levenkov Aug 14 '20 at 02:17
  • @AlexeiLevenkov I have reasons for wanting an async wrapper around sync method and I understand why async is better. I do want a task returned as in the first code snippet. I'm not following what more you are looking for regarding routeDataList. What other options are there when return is List ? The answer I marked as correct is what I was looking for. Thanks for helping though. – Pete Aug 16 '20 at 22:49
  • @41686d6564 I didn't post my reason because it would have distracted from my question, but since you asked, I have a caching pattern that I use that 99% of the time benefits from await. Occasionally, I have a List like this and it's easier to just code it as a return task rather than write a bunch of extra code in my caching methods to handle synchronous calls. Make sense? (BTW, the answer I checked did solve my problem but thanks for taking the time to help) – Pete Aug 16 '20 at 22:52
  • @Pete you've accepted answer that neither making async wrapper for synchronous method (as it will continue running on the same thread synchronously) nor really returning `Task` (I mean... you can infinitely nest `await Task.FromResult(await Task.FromResult(... (actualResult))))` but why would one want to slow things down just to use `await` somewhere in the code?). Jeremy's answer shows how it is expected to be done - would save you a lot of writing comments explaining *why* you `await` result of `Task.FromResult` call. – Alexei Levenkov Aug 17 '20 at 21:08
  • @AlexeiLevenkov still a little confused. Will the accepted answer effectively do the same thing (nothing worse) then Jeremy's first answer? That is, just synchronous return while using the async and await keywords? If so, that's what I'm looking for. The method that GetAllRoutes ultimately calls has a sig like this: "public async Task Get(string key, Func> func, int? cacheTimeOutSeconds = null)" – Pete Aug 18 '20 at 22:41
  • @AlexeiLevenkov continuing... Jeremy's first answer gives me this syntax error blocking compile, where as accepted answer does not and my app works using it. "Cannot convert expression type 'System.Threading.Tasks.Task>' to return type 'System.Threading.Tasks.Task>' (method) List GraphQL.Repositories.RouteDataRepository.GetRoutesAll()" – Pete Aug 18 '20 at 22:44
  • 1
    https://stackoverflow.com/a/26898326/477420. – Alexei Levenkov Aug 19 '20 at 01:02

3 Answers3

1

You have two options. Just return the value without the await;

public async Task<IEnumerable<RouteData>> GetAll()
{
   return GetRoutesAll();
}

Which would work, but is inefficient. Hence why that will give you a compiler warning.

Or drop the async from the method and return a Task that's already completed;

public Task<IEnumerable<RouteData>> GetAll()
{
   return Task.FromResult(GetRoutesAll());
}

async isn't actually part of the method signature. It's a keyword that causes the compiler to transform your method into something else (see gory details).

Jeremy Lakeman
  • 9,515
  • 25
  • 29
-1
public async Task<IEnumerable<RouteData>> GetAll()
{
   return await Task.FromResult<IEnumerable<RouteData>>(GetRoutesAll());
}
AnGG
  • 679
  • 3
  • 9
-2
public async Task<IEnumerable<RouteData>> GetAll()
    {
        return await Task.Run(()=> GetRoutesAll()); 
    }

This may help you.

Alan
  • 17
  • 4