Defending against race conditions in System.Collec

2019-04-10 22:43发布

问题:

The .NET ConcurrentDictionary is susceptible to a race condition that may cause unexpected data as explained at the bottom of this MSDN article. I'm assuming that there are several factors to take into account.

Q: How should I write code that is not vulnerable to that race condition that may cause data loss?

In my scenario I have an input stream that has an always increasing index (n++). My thought is that I could detect missing data if the race condition occurs and re-send it. On the other hand, there may be a better way to do this that I'm unaware of.

回答1:

There is a general pitfall with concurrent collections (not limited to .net) that people have to be aware of, which is that individual operations may be thread-safe, but sequences of operations are not atomic. What I mean by this is the following: assume this scenario, where I have a concurrent collection with a Check and an Add operation, both atomic.

What I want to do is check if a value exists and if not, add it. So I can write this:

if(!collection.Check(value)) 
{
    collection.Add(value);
}

Although both operations are atomic, the above sequence is not, as a thread may be interrupted between the check and the add by another thread, which leads to inconsistent results. Thus, the entire sequence should be made atomic by wrapping it in a lock statement for example.

lock(locker)
{
   if(!collection.Check(value)) 
   {
       collection.Add(value);
   }
}