skip to Main Content

I have the following interface and two of its implementations:

public interface ITokenCache
{
    string GetToken(string key);
    string SetToken(string key, string value);
    void DeleteToken(string key);
}

public class InMemory : ITokenCache
{          
    // Implementation using IMemoryCache.
}

public class Redis : ITokenCache
{
    // Implemetation using Redis.
}

I’m using APIs from Microsoft.StackExchange.Redis when working with redis and they support asynchronous methods. But IMemoryCache don’t. Therefore, I can make the methods defined in ITokenCache "looking awaitable" such as,

public async Task<string> GetToken(string key)
{
    return _memoryCache.Get(key) as string;
}

If I choose this way, I get multiple compiler warnings as I await nothing in the InMemory implementation. When looking for a solution, one answer suggested using await Task.Delay(0) in the InMemory implementation. (It appeared as only a workaround to suppress compiler warning.)

But also, docs recommend not to use methods such as Task.Run in an ASP.NET Core Web Application.

What would be the better way to fulfill my requirement? Should I just ignore the compiler warnings?

3

Answers


  1. You can do this without marking async by returning a Task.FromResult containing your value. This is a will still return a Task, so your method is awaitable, but as there’s nothing to await the Task is simply marked as completed.

    For your void return method, if you need it to be awaitable you can return Task.CompletedTask.

    Login or Signup to reply.
  2. There is no need in having an await here. You can just use Task.FromResult and return it here like this:

    public Task<string> GetToken(string key)
    {
        return Task.FromResult(_memoryCache.Get(key) as string);
    }
    
    Login or Signup to reply.
  3. The quick-fix in this situation is to await something that is already completed, e.g., await Task.CompletedTask;

    However, I prefer just suppressing the warning with a #pragma. This gives the code more clarity: it is in fact a synchronous implementation of an asynchronous method (which is exactly what the warning is saying).

    The problem with Task.FromResult-based approaches is that they do not properly handle exceptions. In a task-returning method, the expectation is that exceptions are placed on the returned task.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search