我的申请表中有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)
?
最佳做法是什么?
答案 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");