2013-10-17 26 views
4

让我们假设我们有两个线程,一个集合:检查元素集合存在于多线程应用程序

ConcurrentDictionary<int, object[]> lists = new ConcurrentDictionary<int, object[]>(); 

1)一个线程处理在集合的元素,然后从集合中删除元素

foreach(object[] elem in lists.Values) 
{ 
    //do somethind 
    lists.TryRemove(key, out vals); 
} 

2)第二个线程添加元素到集合,然后它需要能够检查元素状态:

lists.Add(10, some_object); 

... 

if(lists.ContainsKey(10)) 
{ 

    //How can I be sure that at this moment element is still exists ? 
    //Thread may be preempted after if() {} and second thread 
    //can remove object from collection 
} 
+1

您可能会发现这是一个有趣的阅读:http://msdn.microsoft.com/en-us/library/ff649143.aspx – Bit

回答

5

你想用的TryGetValue,因为这可以确保检查/得到的是原子:

object[] val; 
if(lists.TryGetValue(10, out val)) { 
    // Here you have a reference to the object[], even if it has subsequently been removed 
} 

当然,object[]本身的线程安全是另外一个问题,这是不能被ConcurrentDictionary来解决。 (例如,如果说两个线程以某种方式修改对象,并且对象不是线程安全的,那么您需要在TryGetValue块内使用锁。)

+0

是的,我知道,对象[]在我的情况是线程安全的,感谢您的帮助,这就是我正在寻找:) – user1475692

0

在这种情况下,您需要编写自己的锁定访问字典的代码。在那个时候,不再需要一个并发字典,因为你会在字典之外同步对它的访问,所以基本上重复了这些努力。

// in thread 1 
lock(COMMON_LOCK_OBJECT) 
{ 
    foreach(object[] elem in lists.Values) 
    { 
    //do somethind 
    lists.TryRemove(key, out vals); 
    } 

} 

的螺纹2:

​​