我有一个字典,它以字符串作为键,以异步函数作为值,其定义如下:
_messageMap = new Dictionary<string, Func<UpgradeTask, Task>>
{
{ "Upgrade1", Upgrade1 }
};
函数如下所示:
private async Task Upgrade1(UpgradeTask upgradePayload)
{
await _databaseFunctions.DoUpgrade("Upgrade1", upgradePayload.UpgradeId);
}
所有这些都包含在一个类中,该类有一个execute方法,该方法将通过它获得的字符串调用相应的函数。它本质上是一个回调机制,用于将来事件发生时。Execute看起来像这样:
public async Task Execute(FutureEvent futureEvent)
{
var payLoad = JsonSerializer.Deserialize<UpgradeTask>(futureEvent.Message);
await _messageMap[payLoad.UpgradeId].Invoke(payLoad);
}
型
然而,如果有效负载曾经有一个不在字典中的UpgradeId,那么这似乎会无限期地挂起。
我期望发生的是,如果UpgradeId存在于字典中,它将调用那个函数。实际上,在那种情况下,它工作得很好。但是,如果UpgradeId在字典中不存在的有效载荷中,它将无限期地挂起。就像它在等待一些从未发生的事情。我以为它会跳过它,甚至可能出错。但它只是默默地失败,并永远挂起。这是一个问题,因为它实际上并没有崩溃的应用程序的其余部分。其他一切似乎都工作正常,但没有回调得到处理,如果有一个事件不存在于字典。
为什么会这样呢?我知道我可以事先检查一下字典里是否有这个词。但是我仍然很困惑为什么wait会永远挂在那里。我想知道我做错了什么。
编辑:GitHub上的一个例子:https://github.com/Johnhersh/DictionaryTimerExample很不幸,这是我能得到的最小的了。进一步简化它可以让我在访问该键时得到预期的抛出行为。
1条答案
按热度按时间0wi1tuuw1#
您需要检查字典中是否存在该键。如果不进行检查,
KetNotFoundException
将被抛出,它将停止执行调用Execute方法的方法。它不会挂起,只是停止。所以这是唯一的解决办法
或者
我还建议返回
ValueTask
而不是Task
,以避免在字典中找不到键时分配Task内存