Task in await Task.WhenAll New transaction is not allowed because there are other threads running in the session

1

I'm doing a program Console , where basically it executes these 4 procedures

  • Retrieves a IEnumerable<_Url>
  • Parse these urls
  • Inserts into Database
  • 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 program console looks 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'm doing with EntityFramework because it would be the easiest and then would refactor to Dapper or Ado.Net for maximum performance.

    I do not know if I can ask a 2nd question, but if I do with Ado.Net I would have to create a Parallel.ForEach function to do the insert?

    Today the problem is that I download the photos and this step takes longer than the parsing, so I want to use async correctly to maximize the process, because there are thousands of records every day.

        
    asked by anonymous 10.10.2016 / 19:24

    1 answer

    0

    You can not make two accesses 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.

        
    10.10.2016 / 19:34