Šis raksts ir mašīntulkošanas spoguļraksts, lūdzu, noklikšķiniet šeit, lai pārietu uz oriģinālo rakstu.

Skats: 42759|Atbildi: 5

[Avots] Kāpēc .net/c# uzdevums ir lēnāks nekā pavediens?

[Kopēt saiti]
Publicēts 03.05.2017 16:40:28 | | | |
.NET 4 ietver jaunu nosaukumvietu System.Threading.Tasks, kas satur klases, kas abstrahē pavedienu funkcionalitāti. Izmantojiet ThreadPool fonā. Uzdevums ir vienības darbs, kas jāpabeidz. Šīs vienības darbu var palaist atsevišķā pavedienā vai uzdevumu var sākt sinhroni, kas prasa gaidīt galveno regulēšanas pavedienu. Uzdevumu izmantošana ne tikai nodrošina abstrakcijas slāni, bet arī lielu kontroli pār pamatā esošajiem pavedieniem.
Uzdevumi piedāvā lielu elastību, plānojot veicamo darbu. Piemēram, varat definēt nepārtrauktu uzdevumu — kāds darbs jāveic pēc uzdevuma pabeigšanas. Tas var atšķirt veiksmīgu uzdevumu un nē. Turklāt uzdevumus var sakārtot hierarhijā. Piemēram, vecākuzdevums var izveidot jaunu bērnuzdevumu. Tādējādi tiek izveidota atkarība, tādēļ, atceļot vecākuzdevumu, tiks atcelts arī tā pakārtotais uzdevums.


Mūsdienās ir populāri izmantot uzdevumu izpildes metodes, un tas ir augstas veiktspējas, un es nezinu, kur ir uzdevuma izpilde.

Es pats pārbaudīju uzdevumu un pavedienu, un es uzskatu, ka uzdevums ir ļoti lēns, kas ievērojami ietekmē veiktspēju, un testa kods ir šāds:

Mēs cilpinām metodi 1000 reizes, un pēc tam metode bloķē 100 milisekundes, un testa rezultāts ir šāds:



Rezultātu:
Pavedienu izpilde aizņem 188 milisekundes
Uzdevuma izpilde aizņem 14 671 milisekundes


Ātruma starpība starp abiem ir 78 reizes!!

Uzdevums ir ļoti lēns, nezinu, kāpēc tas notiek, vai kaut kas nav kārtībā ar manu testa kodu vai ko? Es ceru, ka jūs varat paskaidrot, kāpēc tas notiek ...




Iepriekšējo:Ziņojumu sūtīšana ar ASP.NET Core
Nākamo:C# Paralēlā aprēķināšana Parallel.For&Parallel.For
 Saimnieks| Publicēts 13.10.2020 10:47:17 |
tongli1996218 Publicēts 2020-10-13 09:34
Lai nodrošinātu tādu pašu kodu kā Thread, mana darbība ir šāds kods, un iepriekš minētais ir pseidokods
PS: Vienkārši zvaniet gaidīt Task.Delay, nepievienojot ...

Jā, paldies

Uzdevuma izpildes laiks: 117.0357

Kodu var modificēt šādi:

Task.Run aizstāj Task.Factory.StartNew, jo tas automātiski izpako iekšējos uzdevumus.
Task.WaitAll gaida ārēju uzdevumu, nevis iekšēju. Izmantojot Task.Run, nav ligzdotu uzdevumu.


Aplūkojot msdn dokumentāciju, var redzēt, ka Task.Delay metode izveido uzdevumu, kas tiek pabeigts pēc noteikta milisekunžu skaita. (Patiesībā tiks izveidots jauns pavediens, un gaidīšana tiks pievienota, lai gaidītu, kamēr uzdevums tiks izpildīts, es nezinu, vai es pareizi saprotu)

Hipersaites pieteikšanās ir redzama.

Turklāt pastāv atšķirība starp uzdevumu un tukšumu

Uzdevums atgriež asinhronu metodi, kas var gaidīt
Void return asinhronā metode nevar gaidīt, tā darbojas asinhroni, jūs nevarat zināt, kad tas ir izdarīts, jūs nevarat uzraudzīt šīs asinhronās operācijas statusu.


Atsauce:

Hipersaites pieteikšanās ir redzama.
Hipersaites pieteikšanās ir redzama.

Rezumējot: ir problēma ar kodu, man nevajadzētu izmantot Thread.Sleep uzdevuma metodē
Publicēts 21.07.2020 13:09:29 |
Man šodien bija tāda pati problēma, izmantojot vairāku pavedienu AES šifrēšanai, uzdevums ir daudz lēnāks nekā pavediens !!
Vai saimnieks ir atradis iemeslu?
Publicēts 12.10.2020 19:24:48 |
Šo ziņu pēdējo reizi rediģēja tongli1996218 2020-10-12 19:43

Pēc īpašnieka koda pārbaudes, kad programma tiek startēta un palaista vairākas reizes, uzdevuma laiks turpinās samazināties, un manā datorā tas tiks samazināts līdz mazāk nekā Thread, un Thread šajā laikā ir stabils.

Vēlāk tika konstatēts, ka Thread.Sleep(100) metodei bija negatīva ietekme uz Task, bet ne uz Thread, un Thread.Sleep(100) varēja aizstāt ar citu laikietilpīgu programmas pārbaudi, piemēram, skaitlisko pašsaskaitīšanu vai gaidīt Task.Delay(100).

PS: Thread.Sleep pārtrauks pašreizējo pavediena sadalīšanas laiku pēc zvanīšanas, piemēram, Thread.Sleep(0) beigs pašreizējo pavediena sadalīšanas laiku un pārsūtīs to uz citiem pavedieniem, lai to palaistu. Uzdevuma iekšpusē ir pavedienu kopums, kas var optimizēt pavedienu konteksta pārslēgšanu un samazināt CPU zuduma laiku (īpaši daudzkodolu CPU optimizācijai), savukārt Thread.Sleep(100) traucēs uzdevuma sākotnējā pavedienu baseina pārslēgšanas loģiku, izraisot lielu CPU laika zudumu

Ja aizstājat Thread.Sleep(100) ar await Task.Delay(100), jūs atradīsiet, ka uzdevuma laika patēriņš ir tikai lielāks par 100 milisekundēm, kā parādīts zemāk:
privāts void TaskTest()
{
        Thread.Sleep(100);
         ... Darbības veikšana
}
Aizstāts ar
private async void TaskTest()
{
      gaida Task.Delay(100);
      ... Uzdevuma izpilde aizņem vairāk nekā 100 milisekundes, kas ir tāds pats kā sākotnējais Thread.Sleep(100) pavedienam
}




 Saimnieks| Publicēts 12.10.2020 22:53:05 |
tongli1996218 Publicēts 2020-10-12 19:24
Pēc īpašnieka koda pārbaudes, kad programma tiek startēta, uzdevuma laiks turpinās samazināties pēc vairākkārtējas palaišanas, un manā datorā tas tiks samazināts līdz mazāk nekā Thread...

Es mēģināju to mainīt uz šādu kodu:
Uzdevums.Kavēšanās(100000);

Uzdevuma izpildes laiks:14,1306 minūtes, kopējais laiks patiešām ir ļoti īss, tomēr es atklāju, ka uzdevuma izsauktā metode nepabeidza izpildi.
Publicēts 13.10.2020 09:34:33 |
Šo ziņu pēdējo reizi rediģēja tongli1996218 2020-10-13 09:40
Publicēts 2020-10-12 22:53
Es mēģināju to mainīt uz šādu kodu:
Uzdevums.Kavēšanās(100000);

Lai nodrošinātu tādu pašu kodu kā Thread, mana darbība ir šāds kods, un iepriekš minētais ir pseidokods
PS: Vienkārši zvaniet gaidīt Task.Delay un pēc tam nepievienojiet kodu, uzdevuma atvērtais pavediens tiek nekavējoties atgriezts, lai nodrošinātu skaitļošanas simulāciju, varat izmantot (int a = 0; a< 1000000; ++a){}; Šādas metodes tā vietā

privāts asinhrons statisks tukšums TaskTest()
        {
            gaidīt Task.Delay(100000);
             Interlocked.Increment(ref run);    slēdzene, bet pieskaitāmās izmaksas ir mazākas
            if(palaist == j)
             {
                hronometrs. Stop(); Uzraudzības pārtraukšana
                TimeSpan timeinterval = hronometrs. Pagājis;  Iegūst kopējo laiku, ko mēra pašreizējā instance
                Console.WriteLine("Uzdevuma izpildes laiks:" + laika posms. TotalMilliseconds); Kopējais milisekunžu skaits
              }
        Patērētais laiks ir arī ļoti īss


Atruna:
Visa programmatūra, programmēšanas materiāli vai raksti, ko publicē Code Farmer Network, ir paredzēti tikai mācību un pētniecības mērķiem; Iepriekš minēto saturu nedrīkst izmantot komerciāliem vai nelikumīgiem mērķiem, pretējā gadījumā lietotājiem ir jāuzņemas visas sekas. Informācija šajā vietnē nāk no interneta, un autortiesību strīdiem nav nekāda sakara ar šo vietni. Iepriekš minētais saturs ir pilnībā jāizdzēš no datora 24 stundu laikā pēc lejupielādes. Ja jums patīk programma, lūdzu, atbalstiet oriģinālu programmatūru, iegādājieties reģistrāciju un iegūstiet labākus oriģinālus pakalpojumus. Ja ir kādi pārkāpumi, lūdzu, sazinieties ar mums pa e-pastu.

Mail To:help@itsvse.com