2015-01-30 2 views
0

У меня есть класс Test.Обновление ключевого объекта в методе AddOrUpdate

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

Я хотел бы установить ConcurrentDictionary с int как ключом и тестом как значение.

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

Я хотел бы, чтобы написать обновления часть AddorUpdate для этого словаря, так что, если внешняя переменная (скажем, внешняя) истинна тогда Val для этого экземпляра теста должны увеличиваться на 100, но если BOOL ложно, то он должен уменьшаться на 100. Может ли кто-нибудь помочь мне, как я могу это сделать. Я просто не уверен, как получить доступ к экземпляру Test в словаре с помощью лямбда. Также я могу вызвать вызов метода, несмотря на лямбда?

ответ

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, в конечном итоге, как закрытия в анонимный метод, так что получите действительно странно и привести к неожиданным результатам. Вы захотите обойти это как-то.

EDIT:

Я не доволен этим подходом. Я предлагаю перейти на обычный 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(); 
} 

Наконец, не забудьте пометить External как volatile создать барьер памяти и предотвращения оптимизации, которые могут дать вам устаревшее значение.

+0

Могу ли я иметь эту лямбду во внешнюю функцию? Также мне не нужно иметь какие-либо блокировки вокруг этого кода, правильно? –

+2

Вы можете сделать лямбду во внешней функции, я полагаю. Вместо этого я рекомендовал бы мой отредактированный подход. – Haney

+1

Итак, нет способа обращения с закрытием с ConcurrentDictionary? Я знаю с задачами, которые вы можете передать в параметрах, которые делают локальную копию. –

 Смежные вопросы

  • Нет связанных вопросов^_^