为什么我的并行。foreach方法返回错误的值?

发布于 2025-01-28 05:09:08 字数 7379 浏览 3 评论 0原文

我有大量的对象列表(在TXT文件中超过100K行)。我必须使用列表中的每个项目进行一些数据工作,如果它不存在,则将对象保存到数据库中,如果它确实增加了该项目中的数字列,然后在保存更新的项目时更新数据库。

如果我使用常规的foreach循环,一切都很好,但是要完成24小时以上。

问题是,当我使用并行循环时,记录不匹配,有时我会在.save()方法上遇到一个错误,即更改了项目ID。

此代码可行

 public List<SreckaIsplacena> UpisiUTabeleSerijski (List<SreckaTemp>srt)
    {
         _srecke = _glavniRepository.UcitajSamoaktivneSrecke().OrderByDescending(item => item.ID).ToList<Srecka>();
              List<SreckaIsplacena> pomList = new List<SreckaIsplacena>();
              SreckaIsplacena _isplacena;

           foreach (SreckaTemp lt in srt)
           { 
        string beznula = lt.sreIspBroj.TrimStart('0'); 
       
        SreckeDobici srd = new SreckeDobici();
        Srecka sr = (from s in _srecke
                     where s.Sifra == lt.sreSif && s.Serija == lt.sreSerija
                     select s).First();
        List<SreckeDobici> srDob = _glavniRepository.DohvatiSreckeDobiciZaIsplatniBroj(sr, beznula);
        if (srDob.Count == 1)
        {
             srd = srDob.ElementAt(0);
        }
        List<SreckaNagrade> sreckaNagrade = new List<SreckaNagrade>(_glavniRepository.DohvatiNagradeZaSrecku(sr.ID).OrderBy(item => item.SifraFox));
        double iznos = lt.sreIznDob / lt.sreBrDob;

        SreckaNagrade nag = (from sn in sreckaNagrade
                             where sn.Iznos == lt.sreIznDob
                             select sn).FirstOrDefault();
        Odobrenje odo = new Odobrenje();
        odo = odo.DohvatiOdobrenje(valutaGlavna.ID, lt.sreIsplatio).FirstOrDefault();

        List<PorezSrecka> listaPoreza = _glavniRepository.UcitajPorezSrecka(valutaGlavna, odo, sr, nag.NagradaId);
        List<SreckaIsplacena> sveIsplacene = _glavniRepository.DohvatiIsplaceneSreckeZaValutuIProdavacaSreckuNagraduNovo(valutaGlavna.ID, sr.ID, nag.NagradaId, lt.sreIsplatio);
        
        if (sveIsplacene.Count > 1)
        {
            
            System.Windows.MessageBox.Show("Greska, ista srecka s istim dobitkom kod istog prodavaca u istoj valuti 2 put nadjena u bazi");
            
        }

        else if (sveIsplacene.Count == 1)
        {
               _isplacena = sveIsplacene.ElementAt(0);
               
                _isplacena.BrojDobitaka = _isplacena.BrojDobitaka + lt.sreBrDob;               
                _isplacena.Update();

                var index = pomList.FindIndex(r => r.ID == _isplacena.ID);

                if (index != -1)
                {
                    pomList[index] = _isplacena;
                }
        }

        else if (sveIsplacene.Count==0)
        {

             _isplacena = new SreckaIsplacena();
            decimal iz = Convert.ToDecimal(lt.sreIznDob);
            _isplacena.BrojDobitaka = lt.sreBrDob;
            _isplacena.Iznos = iz;
            _isplacena.Nagrada = nag;
            _isplacena.Prodavac = lt.sreIsplatio;
            _isplacena.Valuta = valutaGlavna;
            _isplacena.Srecka = sr;

            _isplacena.Cijena = Convert.ToDecimal(sr.Cijena);
            
            if (listaPoreza.Count == 1)
              {
                  PorezSrecka ps = listaPoreza.ElementAt(0);
                  _isplacena.SreckaPorez = ps;
              }
            
            _isplacena.Save();
            
            int ispID = _isplacena.ID;
            if (ispID != 0)
            {
                srd.Sre_isplatio = lt.sreIsplatio;
                srd.Sre_valuta = valutaGlavna;
                
                srd.Update();    
            }

            pomList.Add(_isplacena);
            
          }

        }       
             return pomList;
    }

此代码

 public List<SreckaIsplacena> UpisiSamoUTabele(ConcurrentBag<SreckaTemp> srt)
    {    
              _srecke = _glavniRepository.UcitajSamoaktivneSrecke().OrderByDescending(item => item.ID).ToList<Srecka>();
              List<SreckaIsplacena> pomList = new List<SreckaIsplacena>();
              SreckaIsplacena _isplacena;
             Parallel.ForEach(srt, (lt) =>
            {                  

        string beznula = lt.sreIspBroj.TrimStart('0');            
        SreckeDobici srd = new SreckeDobici();
        Srecka sr = (from s in _srecke
                     where s.Sifra == lt.sreSif && s.Serija == lt.sreSerija
                     select s).First();
        List<SreckeDobici> srDob = _glavniRepository.DohvatiSreckeDobiciZaIsplatniBroj(sr, beznula);
        if (srDob.Count == 1)
        {
             srd = srDob.ElementAt(0);
        }
        List<SreckaNagrade> sreckaNagrade = new List<SreckaNagrade>(_glavniRepository.DohvatiNagradeZaSrecku(sr.ID).OrderBy(item => item.SifraFox));
       
        SreckaNagrade nag = (from sn in sreckaNagrade
                             where sn.Iznos == lt.sreIznDob
                             select sn).FirstOrDefault();
        Odobrenje odo = new Odobrenje();
        odo = odo.DohvatiOdobrenje(valutaGlavna.ID, lt.sreIsplatio).FirstOrDefault();

        
        List<PorezSrecka> listaPoreza = _glavniRepository.UcitajPorezSrecka(valutaGlavna, odo, sr, nag.NagradaId);
        List<SreckaIsplacena> sveIsplacene = _glavniRepository.DohvatiIsplaceneSreckeZaValutuIProdavacaSreckuNagraduNovo(valutaGlavna.ID, sr.ID, nag.NagradaId, lt.sreIsplatio);
        
        if (sveIsplacene.Count == 1)
        {
             _isplacena = sveIsplacene.ElementAt(0);
           
            lock (_isplacena)
            {
                _isplacena.BrojDobitaka = _isplacena.BrojDobitaka + lt.sreBrDob; 
                _isplacena.Update();

                var index = pomList.FindIndex(r => r.ID == _isplacena.ID);

                if (index != -1)
                {
                    pomList[index] = _isplacena;
                }
                 
            
            }
           
        }

        else if (sveIsplacene.Count==0)
        {
             _isplacena = new SreckaIsplacena();
            decimal iz = Convert.ToDecimal(lt.sreIznDob);
            _isplacena.BrojDobitaka = lt.sreBrDob;
            _isplacena.Iznos = iz;
            _isplacena.Nagrada = nag;
            _isplacena.Prodavac = lt.sreIsplatio;
            _isplacena.Valuta = valutaGlavna;
            _isplacena.Srecka = sr;
            
            
            _isplacena.Cijena = Convert.ToDecimal(sr.Cijena);
          
            lock(_isplacena)
            {
                if (listaPoreza.Count == 1)
                {
                    PorezSrecka ps = listaPoreza.ElementAt(0);
                    _isplacena.SreckaPorez = ps;
                }
            _isplacena.Save();
            
            int ispID = _isplacena.ID;
            if (ispID != 0)
            {
                srd.Sre_isplatio = lt.sreIsplatio;
                srd.Sre_valuta = valutaGlavna; 
                srd.Update();
                
            }
            pomList.Add(_isplacena);
            }
        }

            });
            
             return pomList;

         }

我尝试使用consturrentbag而不是列表,但遇到了一个问题,因为conturrentBag没有FindIndex方法(var index = pomlist.findindex(r =&gt; r.id = == _isplacena.id); )。我知道有某种方法可以取出对象并放回进来,但不确定如何做到这一点,如果您使用我的锁定,从我阅读的列表中可以做到的。

请帮忙。

I have a large List of objects (over 100k rows in a txt file). I have to do some data work with each item in the list I save the object to the database if it doesnt exist and if it does I increase a number column in the for the item and then update the database while saving the updated item.

If I use a regular foreach loop everything works out fine but it takes over 24 hours to finish.

The issue is that when I use a parallel loop the records do not match and sometimes I will get an error on the .Save() method that the item ID was changed.

THIS CODE WORKS

 public List<SreckaIsplacena> UpisiUTabeleSerijski (List<SreckaTemp>srt)
    {
         _srecke = _glavniRepository.UcitajSamoaktivneSrecke().OrderByDescending(item => item.ID).ToList<Srecka>();
              List<SreckaIsplacena> pomList = new List<SreckaIsplacena>();
              SreckaIsplacena _isplacena;

           foreach (SreckaTemp lt in srt)
           { 
        string beznula = lt.sreIspBroj.TrimStart('0'); 
       
        SreckeDobici srd = new SreckeDobici();
        Srecka sr = (from s in _srecke
                     where s.Sifra == lt.sreSif && s.Serija == lt.sreSerija
                     select s).First();
        List<SreckeDobici> srDob = _glavniRepository.DohvatiSreckeDobiciZaIsplatniBroj(sr, beznula);
        if (srDob.Count == 1)
        {
             srd = srDob.ElementAt(0);
        }
        List<SreckaNagrade> sreckaNagrade = new List<SreckaNagrade>(_glavniRepository.DohvatiNagradeZaSrecku(sr.ID).OrderBy(item => item.SifraFox));
        double iznos = lt.sreIznDob / lt.sreBrDob;

        SreckaNagrade nag = (from sn in sreckaNagrade
                             where sn.Iznos == lt.sreIznDob
                             select sn).FirstOrDefault();
        Odobrenje odo = new Odobrenje();
        odo = odo.DohvatiOdobrenje(valutaGlavna.ID, lt.sreIsplatio).FirstOrDefault();

        List<PorezSrecka> listaPoreza = _glavniRepository.UcitajPorezSrecka(valutaGlavna, odo, sr, nag.NagradaId);
        List<SreckaIsplacena> sveIsplacene = _glavniRepository.DohvatiIsplaceneSreckeZaValutuIProdavacaSreckuNagraduNovo(valutaGlavna.ID, sr.ID, nag.NagradaId, lt.sreIsplatio);
        
        if (sveIsplacene.Count > 1)
        {
            
            System.Windows.MessageBox.Show("Greska, ista srecka s istim dobitkom kod istog prodavaca u istoj valuti 2 put nadjena u bazi");
            
        }

        else if (sveIsplacene.Count == 1)
        {
               _isplacena = sveIsplacene.ElementAt(0);
               
                _isplacena.BrojDobitaka = _isplacena.BrojDobitaka + lt.sreBrDob;               
                _isplacena.Update();

                var index = pomList.FindIndex(r => r.ID == _isplacena.ID);

                if (index != -1)
                {
                    pomList[index] = _isplacena;
                }
        }

        else if (sveIsplacene.Count==0)
        {

             _isplacena = new SreckaIsplacena();
            decimal iz = Convert.ToDecimal(lt.sreIznDob);
            _isplacena.BrojDobitaka = lt.sreBrDob;
            _isplacena.Iznos = iz;
            _isplacena.Nagrada = nag;
            _isplacena.Prodavac = lt.sreIsplatio;
            _isplacena.Valuta = valutaGlavna;
            _isplacena.Srecka = sr;

            _isplacena.Cijena = Convert.ToDecimal(sr.Cijena);
            
            if (listaPoreza.Count == 1)
              {
                  PorezSrecka ps = listaPoreza.ElementAt(0);
                  _isplacena.SreckaPorez = ps;
              }
            
            _isplacena.Save();
            
            int ispID = _isplacena.ID;
            if (ispID != 0)
            {
                srd.Sre_isplatio = lt.sreIsplatio;
                srd.Sre_valuta = valutaGlavna;
                
                srd.Update();    
            }

            pomList.Add(_isplacena);
            
          }

        }       
             return pomList;
    }

THIS CODE DOES NOT WORK

 public List<SreckaIsplacena> UpisiSamoUTabele(ConcurrentBag<SreckaTemp> srt)
    {    
              _srecke = _glavniRepository.UcitajSamoaktivneSrecke().OrderByDescending(item => item.ID).ToList<Srecka>();
              List<SreckaIsplacena> pomList = new List<SreckaIsplacena>();
              SreckaIsplacena _isplacena;
             Parallel.ForEach(srt, (lt) =>
            {                  

        string beznula = lt.sreIspBroj.TrimStart('0');            
        SreckeDobici srd = new SreckeDobici();
        Srecka sr = (from s in _srecke
                     where s.Sifra == lt.sreSif && s.Serija == lt.sreSerija
                     select s).First();
        List<SreckeDobici> srDob = _glavniRepository.DohvatiSreckeDobiciZaIsplatniBroj(sr, beznula);
        if (srDob.Count == 1)
        {
             srd = srDob.ElementAt(0);
        }
        List<SreckaNagrade> sreckaNagrade = new List<SreckaNagrade>(_glavniRepository.DohvatiNagradeZaSrecku(sr.ID).OrderBy(item => item.SifraFox));
       
        SreckaNagrade nag = (from sn in sreckaNagrade
                             where sn.Iznos == lt.sreIznDob
                             select sn).FirstOrDefault();
        Odobrenje odo = new Odobrenje();
        odo = odo.DohvatiOdobrenje(valutaGlavna.ID, lt.sreIsplatio).FirstOrDefault();

        
        List<PorezSrecka> listaPoreza = _glavniRepository.UcitajPorezSrecka(valutaGlavna, odo, sr, nag.NagradaId);
        List<SreckaIsplacena> sveIsplacene = _glavniRepository.DohvatiIsplaceneSreckeZaValutuIProdavacaSreckuNagraduNovo(valutaGlavna.ID, sr.ID, nag.NagradaId, lt.sreIsplatio);
        
        if (sveIsplacene.Count == 1)
        {
             _isplacena = sveIsplacene.ElementAt(0);
           
            lock (_isplacena)
            {
                _isplacena.BrojDobitaka = _isplacena.BrojDobitaka + lt.sreBrDob; 
                _isplacena.Update();

                var index = pomList.FindIndex(r => r.ID == _isplacena.ID);

                if (index != -1)
                {
                    pomList[index] = _isplacena;
                }
                 
            
            }
           
        }

        else if (sveIsplacene.Count==0)
        {
             _isplacena = new SreckaIsplacena();
            decimal iz = Convert.ToDecimal(lt.sreIznDob);
            _isplacena.BrojDobitaka = lt.sreBrDob;
            _isplacena.Iznos = iz;
            _isplacena.Nagrada = nag;
            _isplacena.Prodavac = lt.sreIsplatio;
            _isplacena.Valuta = valutaGlavna;
            _isplacena.Srecka = sr;
            
            
            _isplacena.Cijena = Convert.ToDecimal(sr.Cijena);
          
            lock(_isplacena)
            {
                if (listaPoreza.Count == 1)
                {
                    PorezSrecka ps = listaPoreza.ElementAt(0);
                    _isplacena.SreckaPorez = ps;
                }
            _isplacena.Save();
            
            int ispID = _isplacena.ID;
            if (ispID != 0)
            {
                srd.Sre_isplatio = lt.sreIsplatio;
                srd.Sre_valuta = valutaGlavna; 
                srd.Update();
                
            }
            pomList.Add(_isplacena);
            }
        }

            });
            
             return pomList;

         }

I tried using ConcurrentBag instead of List but ran into an issue because ConcurrentBag does not have the FindIndex method (var index = pomList.FindIndex(r => r.ID == _isplacena.ID);). I know there is some way to take out the object and put back in but not sure how to do that and from what I read Lists should be ok if you use locking which I am.

Please help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文