重现 'non-concurrent collections must have exclusive access' 异常
Reproducing the 'non-concurrent collections must have exclusive access' exception
我在生产应用程序中有 https://dotnetfiddle.net/GknA5Q 中描述的以下代码。 dictionary
用作 缓存 以保留对象的属性。使用此 dictionary
的 REST API 有数百种对象类型,因此当 API 找到更多对象类型时,缓存会变大。正如您在代码中看到的那样,通过 reflection 检索对象的属性。当 API 启动并且数百个请求到达 API 时,dictionary
被填充。每个请求都有一个对象类型,其属性正在被缓存。
尽管 REST API 有效,但当 API 在 IIS 中启动时,代码现在会生成以下错误。生成错误的行号是 23,其中 TryGetValue
被调用。
Operations that change non-concurrent collections must have exclusive access. A concurrent update was performed on this collection and corrupted its state. The collection's state is no longer correct.
我正在尝试在测试应用程序中重现相同的错误,因此可以应用一些解决方案。我不想删除 dictionary
,这会增加处理到达 API 的每个请求中每个模型的时间。如果此 dictionary
缓存可用,则可以从缓存中检索属性,而不是通过反射解析。
如何重现上述错误?
Dictionary class 支持多个读取器,但不支持多个写入器。
你可以在这里阅读官方文档
https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2?view=net-5.0#thread-safety
要测试并发性,您可以使用 Parallel class
https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.parallel?view=net-5.0
Parallel.For(0, 1000, i =>
{
// dictionary.Add(...)
});
IDictionary 的线程安全实现是 ConcurrentDictionary class
https://docs.microsoft.com/en-us/dotnet/api/system.collections.concurrent.concurrentdictionary-2?view=net-5.0
您只需将代码中的“Dictionary”替换为“ConcurrentDictionary”
我在生产应用程序中有 https://dotnetfiddle.net/GknA5Q 中描述的以下代码。 dictionary
用作 缓存 以保留对象的属性。使用此 dictionary
的 REST API 有数百种对象类型,因此当 API 找到更多对象类型时,缓存会变大。正如您在代码中看到的那样,通过 reflection 检索对象的属性。当 API 启动并且数百个请求到达 API 时,dictionary
被填充。每个请求都有一个对象类型,其属性正在被缓存。
尽管 REST API 有效,但当 API 在 IIS 中启动时,代码现在会生成以下错误。生成错误的行号是 23,其中 TryGetValue
被调用。
Operations that change non-concurrent collections must have exclusive access. A concurrent update was performed on this collection and corrupted its state. The collection's state is no longer correct.
我正在尝试在测试应用程序中重现相同的错误,因此可以应用一些解决方案。我不想删除 dictionary
,这会增加处理到达 API 的每个请求中每个模型的时间。如果此 dictionary
缓存可用,则可以从缓存中检索属性,而不是通过反射解析。
如何重现上述错误?
Dictionary
你可以在这里阅读官方文档
https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2?view=net-5.0#thread-safety
要测试并发性,您可以使用 Parallel class
https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.parallel?view=net-5.0
Parallel.For(0, 1000, i =>
{
// dictionary.Add(...)
});
IDictionary
https://docs.microsoft.com/en-us/dotnet/api/system.collections.concurrent.concurrentdictionary-2?view=net-5.0
您只需将代码中的“Dictionary”替换为“ConcurrentDictionary”