Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ConcurrentDictionary-坏字典还是坏代码?_C#_Multithreading_Concurrency_Concurrentdictionary - Fatal编程技术网

C# ConcurrentDictionary-坏字典还是坏代码?

C# ConcurrentDictionary-坏字典还是坏代码?,c#,multithreading,concurrency,concurrentdictionary,C#,Multithreading,Concurrency,Concurrentdictionary,好吧,我遇到了一个奇怪的小问题,坦率地说,我已经没有主意了。我想把它扔出去看看我是否遗漏了一些我做错的事情,或者ConcurrentDictionary是否工作不正常。代码如下: (缓存是包含静态ConcurrentDictionary键的类) 问题是偶尔tmp为null,导致TryRemove行运行,而返回null上面的行永远不会被点击。既然returnnull是唯一将null放入字典的东西,而且它从未运行过,那么tmp怎么可能是null 包括缓存类(此代码不使用SetNames): 公共类

好吧,我遇到了一个奇怪的小问题,坦率地说,我已经没有主意了。我想把它扔出去看看我是否遗漏了一些我做错的事情,或者ConcurrentDictionary是否工作不正常。代码如下:

(缓存是包含静态ConcurrentDictionary键的类)

问题是偶尔
tmp
null
,导致
TryRemove
行运行,而
返回null上面的行永远不会被点击。既然
returnnull
是唯一将
null
放入字典的东西,而且它从未运行过,那么
tmp
怎么可能是
null


包括缓存类(此代码不使用SetNames):

公共类缓存
{
公共静态ConcurrentDictionary键=新ConcurrentDictionary();
公共静态ConcurrentDictionary SetNames=新ConcurrentDictionary();
}

tmp
如果从
上下文.GetKeys(key)
返回的不是单个项,则tmp可以为空。在这种情况下,
keys.Count()!=1
,一个空项将插入指定键的
缓存.Keys
(并从
GetOrAdd
返回,并分配给
tmp


编辑:只是想到了另一种可能性。关键是什么数据类型?它是某种自定义类吗?看起来是的。如果是这样的话,您是否正确地实现了
Equals
GetHashcode

我应该在一段时间前关闭它,但我完全忘记了它。该示例不是线程安全的,因为
TryRemove
,但添加该示例只是为了调试目的。最后,我通过重写解决了这个问题,因此,关于代码过时的一些评论可能是正确的。但是,该代码不再存在以进行确认


我把这一点归咎于用户错误(当然是我自己的错误)。谢谢大家的时间

可能字典中已经有一个
null
值?有多少线程正在运行此代码?它似乎不是线程安全的。@Ilykogan-不,字典在启动时是空的,并且从不包含空值,即使遇到
if(tmp==null)
中的断点。@oleksii我完全希望它是线程安全的。你能指定你认为会引起问题的区域吗?你确定线永远不会被击中吗?断点是在lambda中显式设置的,而不是在语句本身上设置的?但是OP声明从未执行
返回null
行,如果正确,这意味着您的场景永远不会发生。@phoog是正确的-我还仔细检查了传入参数以及
上下文.GetKeys(key)
,此数据不会出现这种情况。我希望将来会发生这种情况,但这不是问题所在。那么OP就错了:-)要么字典包含指定键的null,要么执行返回null行。现在,从变量名来看,我对Keys成员的GetOrAdd调用表示怀疑,但那是另一回事了。@ChrisShain我明白你的意思,我一直在努力找出哪一个是这样的。我写这篇文章的原因是因为在任何情况下,这两个都不是问题,这是没有意义的。如果
Cache.Keys
曾经包含
null
,则
return null
上的断点已断开。@chrishain该键是一个.net
类型
对象
var tmp = Cache.Keys.GetOrAdd(type,
                key =>
                {
                    var keys = context.GetKeys(key);
                    if (keys.Count() == 1)
                    {
                        return new KeyInfo
                            {
                                Name = keys.First().Name,
                                Info = key.GetInfo(keys.First().Name)
                            };
                    }

                    return null;
                });

            if (tmp == null)
                Cache.Keys.TryRemove(type, out tmp);

            return tmp;
public class Cache
{
    public static ConcurrentDictionary<Type, Info> Keys = new ConcurrentDictionary<Type, Info>();
    public static ConcurrentDictionary<Type, string> SetNames = new ConcurrentDictionary<Type, string>();
}