为什么我的并行。foreach方法返回错误的值?
我有大量的对象列表(在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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论