0

テストクラスがあります。

class Test
{
    public int Id { get; set; }
    public int Val { get; set; }
}

int を Key として、Test を値として ConcurrentDictionary をセットアップしたいと思います。

bool External = true;
ConcurrentDictionary<int, Test> data = new ConcurrentDictionary<int, Test>();

このディクショナリの AddorUpdate の Update 部分を記述して、外部変数 (External など) が true の場合、Test のそのインスタンスの Val が 100 ずつ増加し、bool が false の場合は 100 ずつ減少するようにしたいと思います。誰かが私を助けてくれます。ラムダを使用して辞書内の Test インスタンスにアクセスする方法がわかりません。また、ラムダにもかかわらずメソッド呼び出しを行うことはできますか?

4

1 に答える 1

2

何かのようなもの:

data.AddOrUpdate(key, test, (k, t) =>
{
    var newTest = new Test { Id = t.Id, Val = t.Val };
    if (External)
        newTest.Val += 100;
    else
        newTest.Val -= 100;

    return newTest;
});

あなたのbool例では、 は匿名メソッドのクロージャーExternalとして終了するため、非常に奇妙になり、予期しない結果が発生します。どういうわけかそれを回避したいと思うでしょう。

編集:

私はこのアプローチに満足していません。私は定期的に行きDictionary<int, Test>、現在の値を引き出して更新することをお勧めしReaderWriterLockSlimます。

var key = ...;
var lock = new ReaderWriterLockSlim();

lock.EnterWriteLock();
try
{
    if (dict.ContainsKey(key))
    {
        // update without closures
        var test = dict[key];
        if (External)
            test.Val += 100;
        else
            test.Val -= 100;
    }
}
else
{
    // insert
    var test = new Test { ...initial state... };
    dict.Add(key, test);
}
finally
{
    lock.ExitWriteLock();
}

最後に、メモリ バリアを作成し、古い値を与える可能性のある最適化を防ぐために、必ずExternalasをマークしてください。volatile

于 2015-01-30T16:23:11.253 に答える