2 回答
TA贡献1864条经验 获得超2个赞
我的目标是在一段时间后删除一个项目。
那为什么不使用缓存呢?
使用 async void 好吗?
的准则async void
是避免async void
,除非您正在实现事件处理程序(或逻辑上类似于事件处理程序的东西)。所以这里真正的问题是:RemoveLately
逻辑上是一个“事件处理程序”吗?我可以看到一个可以被认为是一个论点的论点;具体来说,TryRemove
调用以响应计时器“事件”( Task.Delay
)。所以我不会绝对地说这async void
是错误的,但它确实有缺点。
如果有的话,这种做法的缺点是什么?
方法有一个主要问题async void
:其他代码无法知道该方法何时完成。
这个主要问题表现在几个方面:
您的代码无法捕获或处理来自
RemoveLately
. 由于无法观察async void
方法的完成情况,因此也无法观察异常。因此,async void
方法只是直接在其原始SynchronizationContext
. 在大多数情况下,这意味着方法中的异常async void
会使应用程序崩溃。async void
方法很难测试。这是因为单元测试代码无法知道async void
方法何时完成。您的代码无法知道何时可以安全关闭(其中“关闭”的范围可能意味着“退出程序”或“处置
StateManager
”或介于两者之间的任何内容)。这是因为您的代码无法知道是否有async void
工作仍在进行中。在这种只是从缓存中删除对象的特殊情况下RemoveLately
,这应该可以忽略,但在一般情况下async void
意味着应用程序永远不知道它何时“完成”。
TA贡献1784条经验 获得超9个赞
没有 async void (几乎)总是不好的(例如this)。正如 Stephen 在他的文章和此处的回答中所述,有一些理由需要使用异步 void 方法(即异步事件处理程序,除了 void 之外没有任何其他“返回”值)。斯蒂芬在他的回答中解释了您应该更改为异步任务的原因以及它们更好的原因。
这就是为什么我建议您的方法应该如下所示:
private async Task RemoveLately(int id)
{
await Task.Delay(10000).ConfigureAwait(false);
_states.TryRemove(id, out _);
}
作为一个小评论(如果我可以的话):如果你不确定选择什么和/或你可以选择Task(或Task<T>)或者async void然后尝试使用Task因为在几乎所有情况下(事件处理除外)你Task都比与async void。
- 2 回答
- 0 关注
- 80 浏览
添加回答
举报