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
You can do this without marking
async
by returning a Task.FromResult containing your value. This is a will still return aTask
, so your method is awaitable, but as there’s nothing to await theTask
is simply marked as completed.For your
void
return method, if you need it to be awaitable you can return Task.CompletedTask.There is no need in having an await here. You can just use
Task.FromResult
and return it here like this: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.