datoru programmēšana termins “pavediens” ir īss izpildes pavedienam, kurā procesors seko noteiktam ceļam caur jūsu kodu. Vairāk nekā viena pavediena vienlaicīgas sekošanas jēdziens ievieš daudzuzdevumu un vairāku pavedienu tēmu.
Lietojumprogrammā tajā ir viens vai vairāki procesi. Domājiet par procesu kā programmu, kas darbojas jūsu datorā. Tagad katram procesam ir viens vai vairāki pavedieni. Spēles lietojumprogrammai var būt pavediens, lai ielādētu resursus no diska, cits - lai veiktu AI, un cits - lai palaistu spēli kā serveri.
.NET / Windows operētājsistēma procesora laiku piešķir pavedienam. Katrs pavediens seko izņēmumu apstrādātājiem un prioritātei, kurā tas darbojas, un tam ir kaut kur jāsaglabā pavediena konteksts, līdz tas darbojas. Pavediena konteksts ir informācija, kas ir jāatjauno.
Daudzuzdevumu veikšana ar pavedieniem
Vītnes aizņem nedaudz atmiņas, un to izveidošana prasa nedaudz laika, tāpēc parasti jūs nevēlaties tos izmantot daudz. Atcerieties, ka viņi sacenšas par procesora laiku. Ja jūsu datoram ir vairāki CPU, tad Windows vai .NET katru pavedienu var palaist citā CPU, bet, ja vairāki pavedieni darbojas vienā un tajā pašā CPU, tad vienlaikus var būt aktīvs tikai viens, un pavedienu pārslēgšana prasa laiku laiks.
Centrālais procesors vada pavedienu dažiem miljoniem instrukciju, un pēc tam tas pārslēdzas uz citu pavedienu. Visi CPU reģistri, pašreizējais programmas izpildes punkts un kaudze ir jāsaglabā kaut kur pirmajam pavedienam un pēc tam no kaut kur citur jāatjauno nākamajam pavedienam.
Vītnes izveidošana
Nosaukumu telpā. Vītne, jūs atradīsit pavediena veidu. Konstruktora pavediens (ThreadStart) izveido pavediena gadījumu. Tomēr nesen C # kodu, tas, visticamāk, iet caur lambda izteiksmi, kas izsauc metodi ar visiem parametriem.
Ja neesat pārliecināts par to lambda izteicieni, varētu būt vērts pārbaudīt LINQ.
Šeit ir izveidota un sākta pavediena piemērs:
izmantojot Sistēmu;
izmantojot sistēmu. Vītne;
nosaukumvieta ex1
{
klases programma
{
public static void Write1 ()
{
Konsole. Rakstīt ('1');
Vītne. Gulēt (500);
}
static void Main (virkne [] args)
{
var uzdevums = jauns pavediens (Write1);
uzdevums. Sākt() ;
par (var i = 0; i <10; i ++)
{
Konsole. Rakstīt ('0');
Konsole. Rakstīt (uzdevums. Ir dzīvs? 'A': 'D');
Vītne. Gulēt (150);
}
Konsole. ReadKey ();
}
}
}
Viss šis piemērs nozīmē konsolei rakstīt “1”. Galvenais pavediens 10 reizes konsolei raksta "0", katru reizi seko "A" vai "D" atkarībā no tā, vai otrs pavediens joprojām ir dzīvs vai miris.
Otrais pavediens darbojas tikai vienreiz un raksta “1.” Pēc pussekundes kavēšanās Write1 () pavedienā pavediens tiek pabeigts un Uzdevums. IsAlive galvenajā cilpā tagad atgriež "D."
Vītņu baseins un uzdevumu paralēlā bibliotēka
Tā vietā, lai izveidotu savu pavedienu, ja vien jums tas patiešām nav jādara, izmantojiet pavedienu baseinu. No .NET 4.0 mums ir pieeja uzdevumu paralēlajai bibliotēkai (TPL). Tāpat kā iepriekšējā piemērā, mums atkal ir vajadzīgs mazliet LINQ, un jā, tas viss ir lambda izteiksmes.
Uzdevumi izmanto Vītņu baseins aiz ainas, bet labāk izmantot pavedienus atkarībā no izmantotā skaita.
Galvenais TPL objekts ir uzdevums. Šī ir klase, kas apzīmē asinhrono darbību. Visizplatītākais veids, kā sākt darboties, ir uzdevums. Rūpnīca. SāktJauns kā:
Uzdevums. Rūpnīca. StartNew (() => DoSomething ());
Kur DoSomething () ir palaistā metode. Ir iespējams izveidot uzdevumu, nevis to uzreiz palaist. Tādā gadījumā vienkārši izmantojiet uzdevumu šādi:
var t = jauns uzdevums (() => konsole. WriteLine ("Sveiks"));
...
t. Sākt();
Vītne netiek sākta, kamēr netiek izsaukts .Start (). Zemāk redzamajā piemērā ir pieci uzdevumi.
izmantojot Sistēmu;
izmantojot sistēmu. Vītne;
izmantojot sistēmu. Vītne. Uzdevumi;
nosaukumvieta ex1
{
klases programma
{
public static void Write1 (int i)
{
Konsole. Rakstīt (i);
Vītne. Gulēt (50);
}
static void Main (virkne [] args)
{
par (var i = 0; i <5; i ++)
{
var vērtība = i;
var runTask = Uzdevums. Rūpnīca. StartNew (() => Write1 (vērtība));
}
Konsole. ReadKey ();
}
}
}
Palaidiet to, un jūs saņemsit ciparus no 0 līdz 4 izejā nejaušā secībā, piemēram, 03214. Tas ir tāpēc, ka uzdevumu izpildes secību nosaka .NET.
Jums varētu rasties jautājums, kāpēc ir nepieciešama var vērtība = i. Mēģiniet to noņemt un piezvanīt Write (i), un jūs redzēsit kaut ko negaidītu, piemēram, 55555. Kāpēc ir šis? Tas ir tāpēc, ka uzdevums parāda i vērtību vērtību uzdevuma izpildes laikā, nevis tad, kad uzdevums tika izveidots. Izveidojot jaunu mainīgs katru reizi cilpā katra no piecām vērtībām tiek pareizi saglabāta un paņemta.