0

我的IDictionary<TKey, IList<TValue>>应用程序中有一个。用户有如下请求:

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

但是,只有在所有指定元素都存在时才应进行删除。如果字典有 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)线程安全方法的包装类是最佳实践吗?

最佳做法是什么?

4

2 回答 2

1

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

如果您的需求变得复杂,这也将允许您替换字典。它在一个地方实现了锁定,而调用者不必担心它。

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

于 2013-09-02T20:18:53.713 回答
1

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

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");
于 2013-12-08T09:22:53.833 回答