Use Dbset.add () to discover a series of multithreading problems and solutions in parallel _c# tutorials

Source: Internet
Author: User

Find problems

The demand is very simple, basically is to write the data to the database in bulk, so it is intended to write in a parallel parallel way, hoping to use the computer multi-core features to speed up the program execution speed. Think very well, and then quickly a string of code similar to the following:

using (var db = new Smsentities ())
{
parallel.for (0, 1000, (i) =>
{
db. Membercard.add (New Membercard ()
{
Cardno = "No_" + i.tostring (), banlance
= 0,
createtime = DateTime.Now,
Name = "Test_" + i.tostring (),
Status = 1
});
Db. SaveChanges ();
}

But unexpectedly is the relentless error:

The wonderful thing is when I refresh again when the exception is not the same, so connected to refresh several times, summed up the anomalies have the following:

1, the object reference is not set to an instance of the object.

2, an item with the same key has been added.

3. The collection has been modified; The enumeration operation may not be performed.

4, a edmtype cannot be mapped to a CLR class multiple times. Edmtype "Smsmodel.membercard" has been mapped more than once.

where 1 and 2 are the most, and all the exceptions are in the add, all kinds of eating melon expression ~ No way, and then one by one breakpoint debugging, or did not find out why, for the progress of consideration, replaced by another scheme, that is, using Dbset AddRange method. Add an entity list to the parallel first, then adding it to the dbset at once, and the code evolves as follows:

list<membercard> list = new list<membercard> ();
using (var db = new Smsentities ())
{
var result = Parallel.For (0, 1000, (i) =>
{
list. ADD (New Membercard ()
{
Cardno = "No_" + i.tostring (),
banlance = 0,
createtime = DateTime.Now,
Name = "Test_" + i.tostring (),
Status = 1
});
if (result. iscompleted)
{
db. Membercard.addrange (list);
Db. SaveChanges ();
}

Then compile, test, no problem, put it first.

Analyze problems

The next day to the company's heart is still struggling with this problem, so open the page input generated data volume 1000 (the actual project in the number of cycles is manual input), point button submit, well, eat melon-like abnormal ... :

Thought yesterday Test all good AH (actually yesterday entered is 10, diffident face ... , no way, on the breakpoint, a look startled:

Clearly cycle 1000 times, the result is only 971 data, and there are also null, after many debugging found that this is a random phenomenon, count is random null is also random, sometimes appear sometimes not, preliminary judgment this is a resource leveling exception that is raised in multi-threaded situations. So, on MSDN to see the list of the introduction, the last "thread-safe" reads:

Everything seems clear, so I intend to verify the results, plus the lock, the test results are:

There is no more null in the list, confirming that the exception is caused by multithreading security. Then think of yesterday that question is the same problem, and then on MSDN Search DbContext class and Dbset class, are said:

Then the lock on the DbContext, test, this time finally as I expected, the perfect operation. But puzzled is how the first few anomalies are produced, although the number of the list is not enough also exist as null objects, but did not directly burst the exception. Now only know is the thread problem, and then the details are not clear, there is the great god of the know also trouble pointing.

Find solutions and validate conclusions

Also want to use partitioner partition to do, but carefully think, although the partition is a single thread, but between the district or multi-threaded, if the minute too thin also lost the meaning of parallel, had to find another way out. Fortunately the framework for us also provides a number of thread-safe generic collection (such as Concurrentbag, Concurrentqueue, etc.), but its nature is still used locks, so on the synthesis of a single thread list, multithreaded list lock, Multithreading Concurrentbag, multithreaded Concurrentqueue Performance comparison, the results are as follows:

Cycle 1000 times:

Cycle 10,000 times:

Cycle 100,000 Times:

The conclusion is that the thread-safe type will be slower when the number of executions is too high, and the thread-safe type has no advantage when performed infrequently.

Solve the problem

Finally, after careful testing and consideration of the actual needs of the project (almost impossible once 10000), to simplify, return to the original, with the simplest straightforward way of writing a single thread loop to complete. Although a toss or go back to the beginning, but this process let me find the unexpected problem, and then found the reason, and then test the verification, finally got the best solution. Or that sentence, fill the pit, you are more powerful than before!

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.