Task em await Task.Whenall New transaction is not allowed because there are other threads running in the Session

Asked

Viewed 82 times

1

I’m doing a show Console, where he basically performs these 4 procedures

  1. Recovers a IEnumerable<_Url>
  2. Make a stop on those urls
  3. Inserts to the Database
  4. Mark this _Url as read (processed) so it does not process anymore

But I’m getting an error:

> New transaction is not allowed because there are other threads running in the session.

My console program is like this:

  private static void Main(string[] args)
    {
        IEnumerable<Urls> registros = db.UrlsTable.Where(w => w.Lido == false).Take(10);

        ExecutaTarefasAsync(registros).Wait();
    }



public static async Task ExecutaTarefasAsync(IEnumerable<Urls> registros)
        {
            var urlTasks = registros.Select((registro, index) =>
            {
                //parsing html
                var modelProduto = ExtraiDados.ParserHtml(registro.Url);
                db.Produto.Add(modelProduto);

                //save Database
                var downloadTask = db.SaveChangesAsync();


                //marca url como lida
                registro.Lido = true;
                db.Entry(registro).State = EntityState.Modified;
                db.SaveChangesAsync();

                return downloadTask;
            });

            await Task.WhenAll(urlTasks);
        }

Initially I am doing with Entityframework because it would be the easiest way and then refactoring to Dapper or Ado.Net for maximum performance.

I don’t know if I can ask a second question, but if I do it with Ado.Net I would have to create a function Parallel.ForEach to make the Insert ?

Today the problem is that I download the photos and this step takes longer than Parsing, so I want to use async properly to maximize the process, until pq are thousands of records every day.

  • I’m starting to think that the problem is a limit of the Entity trying to run it inside the loop, I’ll try to do a solution in Ado.Net with Parallel.Foreach

  • You are sharing the same session on more than one task... to solve the problem just make the ExecutaTarefasAsync own db, creating in such a way that ensures that the method has its own session connected to the bank.

1 answer

0


You can’t do two hits async in the same context at the same time:

public static async Task ExecutaTarefasAsync(IEnumerable<Urls> registros)
        {
            var urlTasks = registros.Select((registro, index) =>
            {
                //parsing html
                var modelProduto = ExtraiDados.ParserHtml(registro.Url);
                db.Produto.Add(modelProduto);

                //save Database
                var downloadTask = db.SaveChangesAsync();


                //marca url como lida
                registro.Lido = true;
                db.Entry(registro).State = EntityState.Modified;
                db.SaveChangesAsync(); << ESSE VAI DAR ERRO

                return downloadTask;
            });

            await Task.WhenAll(urlTasks);
        }

Create two different contexts or wait for one to finish to start another.

  • I understood, and how would I know which task was finished to be able to perform the update? I will try to put this 2nd normal update to see

  • The second task of the method does not even start, will give the same error with a normal savechanges. It has to the first SaveChangesAsync() finish to make a second, even not async

  • I did a test creating a class with Dapper just for testing and then it worked....valeu... was this problem 2 Savechanges() does not roll.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.