6

さて、奇妙な小さな問題に直面しており、率直に言って、アイデアがありません。私はこれをそこに捨てて、何か間違ったことを見逃していないか、または ConcurrentDictionary が正しく機能していないかどうかを確認したかったのです。コードは次のとおりです。

(キャッシュは、静的な ConcurrentDictionary キーを含むクラスです)

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;

問題は、 が であることtmpがありnullTryRemove行が実行されることがありますが、return null;上記の行は決してヒットしません。それが辞書にreturn null入れられる唯一のものであり、決して実行されないので、どうしてそうなるでしょうか?nulltmpnull


Cache クラスを含めます (このコードでは SetNames を使用しません):

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

2 に答える 2

3

tmpからセットされた単一のアイテム以外のものを取得した場合、nullになる可能性がありますcontext.GetKeys(key)。その場合keys.Count() != 1、、、およびnullアイテムが、指定されたキーに挿入さCache.Keysれます(そして、から返されGetOrAdd、に割り当てられtmpます)。

編集:別の可能性を考えました。キーはどのデータ型ですか?ある種のカスタムクラスですか?どうやらそうです。もしそうなら、あなたは適切に実装Equalsしましたか?GetHashcode

于 2012-01-05T22:14:17.117 に答える
1

しばらく前にこれを閉じる必要がありましたが、完全に忘れていました。この例は のためスレッドセーフではありませんがTryRemove、これはデバッグ目的でのみ追加されました。私はそれを書き直すことで問題を回避することになったので、おそらくコードが古くなったというコメントのいくつかは正しいでしょう. ただし、確認のためのコードはもう存在しません。

私はこれをユーザーエラーまでチョークしています(もちろん私自身のものです)。みんなの時間をありがとう!

于 2013-12-09T19:16:29.597 に答える