How can I run this entity framework sample faster

前端 未结 2 1398
生来不讨喜
生来不讨喜 2021-01-06 16:50

I have this code for adding about 1500 record to database:

async void button7_Click(object sender, EventArgs e)
{
    var task = await Task.Run(() =>
             


        
2条回答
  •  臣服心动
    2021-01-06 17:22

    Parallel processing won't be of big help here, because your loop by itself takes no time at all. All consumed time goes into two things:

    1. When you add new item to Entity Framework context (and you use EF here as I understand) - it performs some operations on many items in the context (not just the item you added) and it goes slower and slower the more items you added.

    2. Perfoming 1500 database inserts also takes some time.

    The easiest thing to do here is to reduce time taken by point 1 in the list above. You can do it like this:

    async void button7_Click(object sender, EventArgs e)
    {
        var task = await Task.Run(() =>
        {
            Random rnd = new Random();
            var tbls = new List();
            for (int i = 0; i <= 1500; i++)
            {
                tbls.Add(new Tbl()
                {
                    Name = "User" + i + 1,
                    Num = rnd.Next(10, i + 10) / 10
                });
                progress.Report(i * 100 / 1500);
             }
            db.Tbls.AddRange(tbls);
            db.SaveChanges();
            return db.Tbls.Count();
    
        });
    }
    

    By using AddRange and first collecting all items in simple List you will greately reduce time consumed by your code to at least below 1 second.

    Update. If you want to use parallel loop, even if that won't help, you can do it like this:

    int seed = Environment.TickCount;
    var random = new ThreadLocal(() => new Random(Interlocked.Increment(ref seed)));
    var tbls = new ConcurrentBag();
    Parallel.For(0, 1500, (i) => {
        tbls.Add(new Tbl()
        {
            Name = "User" + i + 1,
            Num = random.Value.Next(10, i + 10) / 10
        });
    });                
    db.Tbls.AddRange(tbls);
    

    Things to note:

    • Random is not thread safe so we use thread local instances (one for each thread inside parallel loop), each one with different seed value.
    • List is not thread safe - we use ConcurrentBag instead.

提交回复
热议问题