【发布时间】:2022-12-12 20:48:40
【问题描述】:
我有一个字典,其中字符串作为键,异步函数作为值。它是这样定义的:
_messageMap = new Dictionary<string, Func<UpgradeTask, Task>>
{
{ "Upgrade1", Upgrade1 }
};
函数如下所示:
private async Task Upgrade1(UpgradeTask upgradePayload)
{
await _databaseFunctions.DoUpgrade("Upgrade1", upgradePayload.UpgradeId);
}
这一切都包含在一个类中,该类具有一个执行方法,该方法将通过它获取的字符串调用适当的函数。它本质上是一种回调机制,用于将来发生事件时的回调机制。执行看起来像这样:
public async Task Execute(FutureEvent futureEvent)
{
var payLoad = JsonSerializer.Deserialize<UpgradeTask>(futureEvent.Message);
await _messageMap[payLoad.UpgradeId].Invoke(payLoad);
}
然而,如果有效载荷曾经有一个不在字典中的 UpgradeId,这似乎会无限期地挂起。
我期望发生的是,如果 UpgradeId 存在于字典中,它将调用该函数。实际上在那种情况下效果很好。但是,如果 UpgradeId 位于字典中不存在的有效负载中,似乎会发生什么,它会无限期挂起。就好像在等待永远不会发生的事情。我认为它会跳过它,甚至可能会出错。但它只是默默地失败并永远挂起。这是一个问题,因为它实际上并没有使应用程序的其余部分崩溃。其他一切似乎都工作正常,但如果字典中不存在任何一个事件,则不会处理任何回调。
为什么会这样?我知道我可以事先检查它是否存在于字典中。但我仍然很困惑为什么 await 在那一刻永远挂起。我想了解我做错了什么。
【问题讨论】:
-
如果键不在字典中,则抛出异常(KeyNotFoundException)。现在它取决于你最终如何调用 Execute 方法,如果你总是在调用链中
await或者你是否(以及如何)在某个地方处理异常。 -
它没有。由于当您提供不存在的密钥时字典会抛出
KeyNotFoundException,因此不会发生任何调用。您需要找出该异常是如何/在何处被吞噬的,然后弄清楚在那之后发生了什么。也许这是在某个更大的框架内,该框架不断尝试一遍又一遍地处理相同的有效负载。不可能从这里的碎片说 -
我猜从
Execute返回的任务将IsFaulted设置为true。
标签: c# .net dictionary async-await