EF: PROBLEM WITH DBCONTEXT ACCESS FROM 2 DIFFERENT System.Timers.Timer

103 views Asked by At

I have a problem with my console app. I have a main static class contains the dbcontext as public property. When i start the app, my static class execute the following method:

`

  private static void CaricaDatabaseLotti()
        {
            try
            {
                RiempitoriBinsManager.SetRiempitori(ModelLotti.Riempitori.
              Include("BinsAccatastati").
              Include("Bins.Riempimenti").
              Include("Bins.Riempimenti.Prodotto").
              Include("Bins.Riempimenti.Confezione").
              Include("Bins.Riempimenti.RigheRiempimenti").
              Include("Bins.Riempimenti.RigheRiempimenti.BolleEntrate").
                Include("Bins.Riempimenti.RigheRiempimenti.BolleEntrate.DettagliBolla").
              Where(x => x.RiempitoreId >= 1 && x.RiempitoreId <= 13).ToArray());

                PallettizzatoriManager.SetRiempitori(ModelLotti.Riempitori.
            Include("BinsAccatastati").
            Include("Bins.Riempimenti").
            Include("Bins.Riempimenti.Prodotto").
            Include("Bins.Riempimenti.Confezione").
            Include("Bins.Riempimenti.RigheRiempimenti").
            Include("Bins.Riempimenti.RigheRiempimenti.BolleEntrate").
                            Include("Bins.Riempimenti.RigheRiempimenti.BolleEntrate.DettagliBolla").

            Where(x => x.RiempitoreId >= 14 && x.RiempitoreId <= 19).ToArray());

                RapidPackManager.SetRiempitori(ModelLotti.Riempitori.
              Include("BinsAccatastati").
              Include("Bins.Riempimenti").
              Include("Bins.Riempimenti.Prodotto").
              Include("Bins.Riempimenti.Confezione").
              Include("Bins.Riempimenti.RigheRiempimenti").
              Include("Bins.Riempimenti.RigheRiempimenti.BolleEntrate").
                              Include("Bins.Riempimenti.RigheRiempimenti.BolleEntrate.DettagliBolla").

              Where(x => x.RiempitoreId >= 20 && x.RiempitoreId <= 29).ToArray());


                RiempitoriScartiManager.SetRiempitori(ModelLotti.Riempitori.
                   Include("BinsAccatastati").
                   Include("Bins.Riempimenti").
                   Include("Bins.Riempimenti.Prodotto").
                   Include("Bins.Riempimenti.Confezione").
                   Include("Bins.Riempimenti.RigheRiempimenti").
                   Include("Bins.Riempimenti.RigheRiempimenti.BolleEntrate").
                                   Include("Bins.Riempimenti.RigheRiempimenti.BolleEntrate.DettagliBolla").

                   Where(x => x.RiempitoreId >= 32 && x.RiempitoreId <= 36).ToArray());

                BoxFillersManager.Riempitori=(ModelLotti.Riempitori.
                  Include("BinsAccatastati").
                  Include("Bins.Riempimenti").
                  Include("Bins.Riempimenti.Prodotto").
                  Include("Bins.Riempimenti.Confezione").
                  Include("Bins.Riempimenti.RigheRiempimenti").
                  Include("Bins.Riempimenti.RigheRiempimenti.BolleEntrate").

                  Where(x => x.RiempitoreId >= 30 && x.RiempitoreId <= 31).ToArray());


                PallettizzatoriManager.Pallettizzatori = ModelLotti.Pallettizzatori.OrderBy(x => x.Id).Take(6).ToArray();
                RapidPackManager.Pallettizzatori = ModelLotti.Pallettizzatori.Where(x => x.Id >= 7).OrderBy(x => x.Id).Take(10).ToArray();
                BoxFillersManager.Pallettizzatori = ModelLotti.Pallettizzatori.Where(x => x.Id >= 17).OrderBy(x => x.Id).Take(2).ToArray();

                Stages = ModelLotti.Stages.ToArray();

                var left = Stages[0];
                var right = Stages[1];

                var stagesids = Stages.Select(x => x.Id).ToList();


                var lottistage1 = ModelLotti.Lotti.Include("Parametri")
                    .Include("Parametri.CodiciSpecie")
                    .Include("BolleEntrate")
                    .Include("BolleEntrate.DettagliBolla")
                    .Include("Stages")
                    .Where(x => x.Stages.Select(c =>c.Id).ToList().Contains(left.Id));
                var lottistage2 = ModelLotti.Lotti.Include("Parametri").Include("Parametri.CodiciSpecie").Include("BolleEntrate").Include("BolleEntrate.DettagliBolla").Include("Stages").Where(x => x.Stages.Select(c=>c.Id).ToList().Contains(right.Id));

                LottoCorrenteCal1 = lottistage1.Where(x => x.LottoId == lottistage1.Max(X => X.LottoId)).FirstOrDefault();
                LottoCorrenteCal2 = lottistage2.Where(x => x.LottoId == lottistage2.Max(X => X.LottoId)).FirstOrDefault();

                RiempitoriBinsManager.Navetta.SetBinsABordo(ModelLotti.BinsSuNavettaPieni);

                CronologiaScarichi.CaricaUltimiScarichi();
                CronologiaScarichiNavettaPallet.GetUltimi30Scarichi();
               
            }
            catch (Exception ex)
            {
                throw new ModelLottiException(ex);
            }
        }

`

Then I have 2 different timers they access to DbContext, do their job and call ModelLotti.SaveChanges() if necessary. Sometimes, my context fault like:

1- New transaction is not allowed because there are other threads running in the session 2- The transaction operation cannot be performed because there are pending requests working on this transaction

I cannot use just one timer, I need they work totally indipendent. how can I avoid these exeptions? I need to create 2 different dbcontext one for each timer?

I try to implement a method like these for restore datas

`

  internal static void SalvaLottiContext()
        {
            try
            {
                //Console.WriteLine("Richiesta commit database Lotti...");
                
                if (ModelLotti.ChangeTracker.HasChanges())
                {
                    ModelLotti.SaveChanges();
                    Console.WriteLine("Database Lotti Salvato.");
                }
            }
            catch (Exception ex)
            {
                LogRegister.Warning("ERRORE SALVATAGGIO DB LOTTI: " + ex.Message + ex.InnerException?.Message + ex.InnerException?.InnerException?.Message + ". StackTrace: " + ex.StackTrace);

                RipristinaModello();
            }
        }

        internal static void RipristinaModello()
        {
            Console.WriteLine("Database Lotti Ripristinato.");

            try
            {
                ModelLotti = new ModelLotti();

                CaricaDatabaseLotti();

            }
            catch (Exception ex)
            {
                Console.WriteLine("Impossibile Ripristinare Database Lotti.");
            }

        }

`

0

There are 0 answers