Arhiiv

Posts Tagged ‘ParallelLoopState’

Eranditöötlus rööpsilmuses

Mis saab, kui ühes rööpsilmuse lõimes tekkib erand? Teised silmused lõpetavad töö samamoodi nagu Stop()-meetodi puhul. Erandi poolt tekitatud katkestus on suurema prioriteediga kui Stop() ja Break(), aga siiski lubatakse kõigil lõimedel oma käsilolev tsükkel lõpule viia.

Klassil ParallelLoopState on selline asi nagu IsExceptional, mida pikalt töötavad tsüklid saavad aeg-ajalt kontrollida, et siis kiiremini pillid kotti panna. Alltoodud näites ei ole state.IsExceptional kunagi tõene, sest seda küsitakse tsükli alguses ja uut tsüklit ei alustata kunagi, kui mingi tsükkel on erandi tekitanud. Aga pikema tsükli keskel on küsimusel jumet.

static void Main(string[] args)
{
try
{
Parallel.For(0, 20, (i, state) =>
{
if (state.IsExceptional)
Console.WriteLine("Ups!");
else
{
Console.WriteLine(i);
if (i == 3)
throw new Exception("Ämber");
}
});
}
catch (Exception x)
{
Console.WriteLine(x.Message);
}
}

Kui sa selle koodi käivitad, võid näha, et pärast vea genereerimist lõpetavad tsüklid töö, kus keegi parasjagu on. Silmus ise tekitab erandi “One or more errors occurred” ja rohkem infot sisaldab InnerException.

Advertisements

Parallel.For Break ja Stop

Teises artiklis vaatasime, kuidas kasutada Parallel.For() meetodit. Kuidas silmusest välja pääseda? Jadaprogrammis teeksime nii:

for (int i = 0, i < 20, i++)
{
Console.WriteLine(i);
if (i == 10)
break;
};

Rööplemises võib selle jaoks võib võtta objekti tüübiga ParallelLoopState, mis pakub meetodeid Break() ja Stop().

Break() lõpetab kõik lõimed, kuid garanteerib, et lõpetamise ajaks on iga lõim jõudnud sama väärtuseni, mis oli lõimel, mis kutsus välja katkestuse.

Parallel.For(0, 20, (i, state) =>
{
Console.WriteLine(i);
if (i == 10)
state.Break();
}

Minu katsetuse puhul tähendas see, et väljastati arvud 0, 2, 3, 4, 6, 7, 9, 5, 1, 15, 16, 17, 18, 19, 10, 12, 14, 8. Nagu näed, 11 ja 13 on puudu, sest need lõimed olid juba surnud, aga 0 kuni 10 on kindlalt olemas.

Vastupidiselt sellele katkestab Stop() silmuse töö, sõltumata sellest, millisele tasemele teised lõimed on jõudnud. Seega, kui Stop() juhtub lõimes, mis on teistest parasjagu ees, võivad mõned väärtused vahemikust 0 kuni 10 isegi puudu jääda.

Break() ega Stop() ei garanteeri, et ei käivitada rohkem tsükleid kui vaja, ja see on täiesti loomulik, sest kõik lõimed hakkavad kohe täisvõimsusel hagu andma.

Eeltoodud näidet võiks kiirema pidamasaamise huvides muuta siis nii:

if (i >= 10)
state.Stop();

Kui jadaprogrammis on garanteeritud, et i ==10 ja seejärel i ==11, siis rööpes võib vabalt juhtuda, et esiteks i > 10 ja alles seejärel i==10.

Rubriigid:Alustus Sildid:, , ,