英文:
Is it a good idea to call await Task.Delay(0) to make an method "awaitable" in an ASP.NET Core app?
问题
以下是翻译好的部分:
我有以下接口和其两个实现:
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.
}
在使用`Microsoft.StackExchange.Redis`的API与Redis一起工作时,它们支持异步方法。但`IMemoryCache`不支持。因此,我可以使在`ITokenCache`中定义的方法“看起来可等待”,如下所示:
public async Task<string> GetToken(string key)
{
return _memoryCache.Get(key) as string;
}
如果我选择这种方式,在`InMemory`实现中将会出现多个编译警告,因为我没有等待任何内容。在寻找解决方案时,有一个答案建议在`InMemory`实现中使用`await Task.Delay(0)`(它似乎只是用来抑制编译器警告的临时解决办法)。
但是,[文档][1]也建议不在ASP.NET Core Web应用程序中使用诸如`Task.Run`之类的方法。
满足我的要求的更好方式是什么?我应该忽略编译器警告吗?
[1]: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/best-practices?view=aspnetcore-7.0
英文:
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?
答案1
得分: 3
在这种情况下的快速解决方法是await
一个已经完成的任务,例如,await Task.CompletedTask;
然而,我更喜欢通过#pragma
来抑制警告。这样可以使代码更加清晰:实际上这是一个同步实现异步方法(这正是警告所说的)。
基于Task.FromResult
的方法的问题在于它们不能正确处理异常。在返回任务的方法中,期望是将异常放在返回的任务上。
英文:
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.
答案2
得分: 0
你可以在不标记async
的情况下,通过返回一个包含你的值的Task.FromResult<TResult>来完成这个操作。这仍然会返回一个Task
,因此你的方法可以被等待,但由于没有什么需要等待的内容,所以Task
只是被标记为已完成。
对于你的void
返回方法,如果你需要它可以被等待,你可以返回Task.CompletedTask。
英文:
You can do this without marking async
by returning a Task.FromResult<TResult> 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.
答案3
得分: 0
不需要在这里使用 await。您可以使用 Task.FromResult
并像这样返回它:
public Task<string> GetToken(string key)
{
return Task.FromResult(_memoryCache.Get(key) as string);
}
英文:
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);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论