[Accidental mistakes]. Net concurrentdictionary, thread security collection class

Source: Internet
Author: User

Concurrentdictionary is a collection class that is newly added in. Net 4.0 and claims to be thread-safe.

Naturally, we will expectCodeIt is thread-safe (at least several key methods are thread-safe ).

For example, the user may expect the method in getoradd to only execute the Add delegate once when the key does not exist. The second call to getoradd should retrieve the value just generated.

Refer to the following code:

         Public   Static    Void Test ()
{
VaR Concurentdictionary = New Concurrentdictionary < Int , Int > ();

VaR W = New Manualresetevent ( False );
Int Timedcalled = 0 ;
VaR Threads = New List <thread> ();
For ( Int I = 0 ; I <environment. processorcount; I ++)
{
Threads. Add ( New Thread () =>
{
W. waitone ();
Concurentdictionary. getoradd ( 1 , I1 =>
{
Interlocked. increment ( Ref Timedcalled );
Return 1 ;
});
}));
Threads. Last (). Start ();
}

W. Set ();// Release all threads to start at the same time
Thread. Sleep ( 100 );
Console. writeline (timedcalled ); // Output is 4, means call initial 4 times
// Console. writeline (concurentdictionary. Keys. Count );
}

The getoradd method is defined to obtain a value based on the key. If the key does not exist, call func <t> to add a key-value pair.

According to the definition of concurrentdictionary, I expect this add should be called only once

However, the running result of the above Code shows that interlocked. increment (RefTimedcalled); 4 calls, really embarrassing

 

The delegate used for initialization value can also be executed multiple times, so

    • You can also ensure that the code in the delegate is repeat without any problems.
    • Either use a thread-safe initialization method, such as lazy <t>

 

  Public   Static   Void Test ()
{
VaR Concurentdictionary = New Concurrentdictionary < Int , Int > ();

VaR W = New Manualresetevent ( False );
Int Timedcalled = 0 ;
VaR Threads = New List <thread> ();
Lazy < Int > Lazy = New Lazy < Int > () => {Interlocked. increment (Ref Timedcalled ); Return 1 ;});
For ( Int I = 0 ; I <environment. processorcount; I ++)
{
Threads. Add ( New Thread () =>
{
W. waitone ();
Concurentdictionary. getoradd ( 1 , I1 =>
{
Return Lazy. value;
});
}));
Threads. Last (). Start ();
}

W. Set (); // Release all threads to start at the same time
Thread. Sleep ( 100 );
Console. writeline (timedcalled ); // Output is 1
}

 

Note: The initialization method will be called multiple times. If this problem is not encountered by accident, it is estimated that the initialization method will never be known.

  //  
// Summary:
// Adds a key/value pair to the system. Collections. Concurrent. concurrentdictionary <tkey, tvalue>
// If the key does not already exist.
//
// Parameters:
// Key:
// The key of the element to add.
//
// Valuefactory:
// The function used to generate a value for the key
//
// Returns:
// The value for the key. This will be either the existing value for the key
// If the key is already in the dictionary, or the new value for the key
// Returned by valuefactory if the key was not in the dictionary.
//
// Exceptions:
// System. argumentnullexception:
// Key is a null reference (nothing in Visual Basic).-Or-valuefactory is a null
// Reference (nothing in Visual Basic ).
//
// System. overflowexception:
// The dictionary contains too extends elements.

 

All the methods using func <t> in this collection class also have similar problems.

I hope to remind friends who do not know the problem to avoid unnecessary bugs.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.