red*_*alx 6 .net dictionary ajaxcontroltoolkit thread-safety
这个问题涉及一个非常具体和常见的场景,其中字典被用于多线程环境中的项目的按需缓存.为了避免线程锁定,最好在同步锁之外测试现有的缓存项,但是如果我们随后必须添加一个项,那么它就算作对字典的写入,因此我在stackoverflow上读到的大多数建议都是你需要锁定读取和写入,因为调用add()可能会改变字典的内部状态.
但是,通过Microsoft的AjaxControlToolkit(scriptObjectBuilder类),代码确实在任何锁之外执行TryGet(),并且只锁定Add()新项到字典.我可以看到,如果放置项目的存储桶在添加后永远不会更改,这可能是怎么可能的,但我怀疑这是错误的,可能是错误的来源.
谢谢.
更新 通过.Net文档我认为所描述的模式确实是错误的.但是我想知道Dictionary的特定实现是否允许它以及AjaxControlToolkit是否依赖于此(这将是可疑的).在检查Reflector中的代码时我很确定这确实是错误的,Dictionary.Resize()方法重新分配桶的数量并移动桶项,因此TryGet()中间的任何线程都可能正在工作在不稳定的数据.
更新 已在codeplex上针对AjaxControlToolkit记录缺陷.看到:
red*_*alx -1
在进行一些投资后回答我自己的问题:在检查 Dictionary 的代码时,我可以看到 Dictionary.Resize() 方法重新分配用于存储数据的内部存储桶的数量,并重新分配存储桶内容,以便项目位于根据哈希码正确存储桶。因此,TryGet() 中间的任何线程都有处理不稳定数据的风险。
顺便说一句,Dictionary 类的一种可能的低锁定方法可能是仅在 Resize() 方法周围放置锁定。