C# 在AddOrUpdate方法中更新密钥对象

C# 在AddOrUpdate方法中更新密钥对象,c#,.net-4.0,concurrentdictionary,C#,.net 4.0,Concurrentdictionary,我有一个测试班 class Test { public int Id { get; set; } public int Val { get; set; } } 我想设置一个ConcurrentDictionary,int作为键,Test作为值 bool External = true; ConcurrentDictionary<int, Test> data = new ConcurrentDictionary<int, Test>(); bool E

我有一个测试班

class Test
{
    public int Id { get; set; }
    public int Val { get; set; }
}
我想设置一个ConcurrentDictionary,int作为键,Test作为值

bool External = true;
ConcurrentDictionary<int, Test> data = new ConcurrentDictionary<int, Test>();
bool External=true;
ConcurrentDictionary数据=新建ConcurrentDictionary();
我想为这个字典编写AddorUpdate的更新部分,这样如果一个外部变量(比如external)为true,那么测试实例的Val应该增加100,但是如果bool为false,那么它应该减少100。有人能帮我吗?我怎么做。我只是不确定如何使用lambda访问字典中的测试实例。也可以在不考虑lambda的情况下调用方法吗?

类似于:

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
,在匿名方法中会以闭包结束,因此它会变得非常奇怪,并产生意外的结果。你会想办法解决这个问题的

编辑:

我对这种方法不满意。我建议去一个常规的
字典
,取出当前值并更新它,所有这些都使用
readerwriterlocksim
来确保状态

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();
}

最后,请确保将
外部
标记为
易失性
,以创建内存屏障并防止可能给您提供过时值的优化。

我可以将此lambda转换为外部函数吗?另外,我不需要在这段代码周围有任何锁,对吗?我想你可以把lambda变成一个外部函数。我建议改用我的编辑方法。所以没有办法用ConcurrentDictionary处理闭包?我知道,对于任务,您可以传入参数以生成本地副本。这里的问题是,
AddOrUpdate
方法有一个特定的签名,如果没有闭包,您就无法真正扩展它以包含变量。