交易字典

时间:2013-09-02 20:12:02

标签: c# collections dictionary transactions thread-safety

我的申请表中有IDictionary<TKey, IList<TValue>>。用户有以下请求:

  

我想取出:TKey = 5的值和TKey的m值= 3。

但是,只有在存在所有指定元素时才应删除。如果字典的n + 3值为TKey = 5,但只有m-1值的TKey = 3 没有元素应该被删除。

保证此交易行为的最佳方法是什么?你会锁定整个字典,然后检查一切是否存在,然后在满足所有指定的查询后删除元素?

有没有办法让字典以某种方式进行交易?类似的东西:

using(var tx = new TransactionScope())
{
  foreach(var query in queries)
    // try to remove elements of query -> exception if not possible -> all others are back in place

  tx.Commit(); // ok, all queries fulfilled, commit now
}

或者最好为字典编写一个包装类,它具有一个线程安全的方法TakeFromDictionary(IEnumerable<Query> queriesWhichMustBeFulfilled)

最佳做法是什么?

2 个答案:

答案 0 :(得分:1)

我会创建一个包装器并在包装器的公共方法中处理锁定。

如果您的要求变得复杂起来,这也可以让您替换字典。它在一个地方实现锁定,而无需打电话者担心。

此外,在字典中使用通用列表变得难以阅读(new Dictionary<String, IList<Int32>>()) - 它可能表示字典过载: - )

答案 1 :(得分:0)

Juval Lowy实施了对象的事务支持。他在这篇MSDN文章中描述了他的工作:http://msdn.microsoft.com/en-us/magazine/cc163688.aspx 在代码示例中,他提供了文章a TransactionalDictionary<T,K>

var dictionary = new TransactionalDictionary<int, string>();
dictionary.Add(1, "A");

// #1: committed transaction
using (var scope = new TransactionScope())
{
    dictionary.Add(2, "B");
    dictionary.Add(3, "C");
    dictionary.Add(4, "D");
    scope.Complete();
}
Debug.Assert(dictionary[3] == "C");

// #2: uncommitted transaction
using (var scope = new TransactionScope())
{
  dictionary[1] = "Z";

  // transaction is not completed -> rollback to initial state 
  //scope.Complete();
}
Debug.Assert(dictionary[1] == "A");