0

我有一个测试课。

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

我想为此字典编写 AddorUpdate 的 Update 部分,以便如果外部变量(例如 External)为真,则该 Test 实例的 Val 应增加 100,但如果 bool 为假,则应减少 100。可以有人帮助我我该怎么做。我只是不确定如何使用 lambda 访问字典中的 Test 实例。尽管有 lambda,我也可以进行方法调用吗?

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

最后,请务必标记Externalvolatile创建内存屏障并防止可能给您提供过时值的优化。

于 2015-01-30T16:23:11.253 回答