Denne artikkelen er en speilartikkel om maskinoversettelse, vennligst klikk her for å hoppe til originalartikkelen.

Utsikt: 42759|Svare: 5

[Kilde] Hvorfor er .net/c# Task tregere enn Thread?

[Kopier lenke]
Publisert på 03.05.2017 16:40:28 | | | |
.NET 4 inkluderer et nytt navnerom, System.Threading.Tasks, som inneholder klasser som abstraherer trådfunksjonalitet. Bruk ThreadPool i bakgrunnen. En oppgave representerer arbeidet til en enhet som bør fullføres. Arbeidet til denne enheten kan kjøres i en separat tråd, eller en oppgave kan startes synkront, noe som krever venting på hovedinnstillingstråden. Å bruke oppgaver gir deg ikke bare et abstraksjonslag, men også mye kontroll over de underliggende trådene.
Oppgaver gir mye fleksibilitet når det gjelder å planlegge arbeidet som må gjøres. For eksempel kan du definere en kontinuerlig oppgave – hvilket arbeid som skal gjøres etter at en oppgave er fullført. Dette kan utgjøre forskjellen mellom en vellykket oppgave og ikke. I tillegg kan oppgaver ordnes i et hierarki. For eksempel kan en foreldreoppgave opprette en ny barneoppgave. Dette skaper en avhengighet slik at hvis du avbryter foreldreoppgaven, vil også dens barneoppgave bli kansellert.


I dag er det populært å bruke metoder for oppgaveutførelse, og det er høyytelse, og jeg vet ikke hvor oppgaveytelsen ligger.

Jeg testet Task og Thread selv, og jeg føler at Task er veldig treg, noe som i stor grad påvirker ytelsen, og testkoden er som følger:

Vi går gjennom metoden 1000 ganger, og så blokkerer metoden i 100 millisekunder, og testresultatet er som følger:



Utfall:
Trådkjøringen tar 188 millisekunder
Oppgaveutførelsen tar 14 671 millisekunder


Hastighetsforskjellen mellom de to er 78 ganger!!

Oppgaven er veldig treg, jeg vet ikke hvorfor dette skjer, er det noe galt med testkoden min, eller hva? Jeg håper du kan forklare hvorfor dette skjer...




Foregående:Send meldinger med ASP.NET Core
Neste:C# Parallell beregning Parallel.For&Parallel.For
 Vert| Publisert på 13.10.2020 10:47:17 |
tongli1996218 Publisert 2020-10-13 09:34
For å sikre samme kode som Thread, er min operasjon følgende kode, og ovenstående er pseudokode
PS: Bare kall await Task.Delay uten å legge til ...

Ja, takk

Oppgaveutførelsestid: 117,0357

Du kan endre koden som følger:

Task.Run erstatter Task.Factory.StartNew fordi den automatisk pakker ut interne oppgaver.
Task.WaitAll venter på en ekstern oppgave i stedet for en intern. Å bruke Task.Run har ikke nestede oppgaver.


Når du ser på msdn-dokumentasjonen, kan du se at metoden Task.Delay Method oppretter en oppgave som fullføres etter et spesifisert antall millisekunder. (Faktisk vil en ny tråd bli opprettet, og await vil bli lagt til for å vente på at oppgaven skal bli utført, jeg vet ikke om jeg forstår riktig)

Innloggingen med hyperkoblingen er synlig.

I tillegg er det forskjell mellom Oppgave og tomrom

Oppgaven returnerer en asynkron metode som kan vente
Void return asynkron metode kan ikke vente, den fungerer asynkront, du kan ikke vite når den er ferdig, du kan ikke overvåke statusen til den asynkrone operasjonen.


Referanse:

Innloggingen med hyperkoblingen er synlig.
Innloggingen med hyperkoblingen er synlig.

Oppsummert: det er et problem med koden, jeg bør ikke bruke Thread.Sleep inne i Task-metoden
Publisert på 21.07.2020 13:09:29 |
Jeg hadde samme problem i dag, brukte multithreading for AES-kryptering, Task er mye tregere enn Thread!!
Har utleieren funnet årsaken?
Publisert på 12.10.2020 19:24:48 |
Dette innlegget ble sist redigert av tongli1996218 den 2020-10-12 kl. 19:43

Etter å ha testet eierens kode, når programmet startes og kjøres flere ganger, vil tiden for oppgaven fortsette å avta, og på min datamaskin vil den bli redusert til mindre enn Thread, og Thread er stabil innenfor denne tiden.

Det ble senere funnet at Thread.Sleep(100)-metoden hadde en negativ innvirkning på Task, men ikke på Thread, og Thread.Sleep(100) kunne erstattes med annen tidkrevende programverifisering som numerisk selvaddisjon eller vent på Task.Delay(100).

PS: Thread.Sleep vil avslutte den nåværende trådslicing-tiden etter kall, for eksempel vil Thread.Sleep(0) avslutte den nåværende trådslicing-tiden og overføre den til andre tråder for å kjøre. Inne i oppgaven finnes en trådpool, som kan optimalisere kontekstbyttet av tråder og redusere CPU-tapstiden (spesielt for multi-core CPU-optimalisering), mens Thread.Sleep(100) vil forstyrre svitsjelogikken til den opprinnelige trådpoolen til oppgaven, noe som forårsaker mye CPU-tidstap

Hvis du erstatter Thread.Sleep(100) med await Task.Delay(100), vil du oppdage at tidsbruken til oppgaven bare er mer enn 100 millisekunder, som vist nedenfor:
privat void TaskTest()
{
        Thread.Sleep(100);
         ... Utfør handlingen
}
Erstattet av
private async void TaskTest()
{
      venter på Oppgave.Forsinkelse(100);
      ... Utførelsen tar mer enn 100 millisekunder for oppgaven, som er det samme som den opprinnelige Thread.Sleep(100) for Thread
}




 Vert| Publisert på 12.10.2020 22:53:05 |
tongli1996218 Publisert 2020-10-12 19:24
Etter å ha testet eierens kode, når programmet startes, vil tiden for oppgaven fortsette å redusere etter flere kjøringer, og på min datamaskin vil den bli redusert til mindre enn Thread...

Jeg prøvde å endre det til kode slik:
Oppgave.Forsinkelse(100000);

Oppgaveutførelsestid:14,1306 ms, den totale tiden er faktisk veldig kort, men jeg oppdaget at metoden som ble kalt av Task ikke fullførte utførelsen.
Publisert på 13.10.2020 09:34:33 |
Dette innlegget ble sist redigert av tongli1996218 den 13.10.2020 kl. 09:40
Publisert 2020-10-12 kl. 22:53
Jeg prøvde å endre det til kode slik:
Oppgave.Forsinkelse(100000);

For å sikre samme kode som Thread, er min operasjon følgende kode, og ovenstående er pseudokode
PS: Bare kall await Task.Delay, og legg deretter til ingen kode, tråden som åpnes av oppgaven returneres umiddelbart, for å sikre simulering av compute-bound, kan du bruke for (int a = 0; a< 1000000; ++a){}; Slike metoder i stedet

privat asynkron statisk void TaskTest()
        {
            vent på Oppgave.Forsinkelse(100000);
             Interlocked.Increment (ref run);    Lås, men taket er mindre
            Hvis(løp == j)
             {
                Stoppeklokke. Stop(); Stopp overvåkingen
                Tidsspenn = stoppeklokke. Passerte;  Får den totale tiden målt av den nåværende instansen
                Console.WriteLine("Oppgaveutførelsestid:" + tidsspenn. TotalMillisekunder); Totale millisekunder
              }
        Tiden det tar er også veldig kort


Ansvarsfraskrivelse:
All programvare, programmeringsmateriell eller artikler publisert av Code Farmer Network er kun for lærings- og forskningsformål; Innholdet ovenfor skal ikke brukes til kommersielle eller ulovlige formål, ellers skal brukerne bære alle konsekvenser. Informasjonen på dette nettstedet kommer fra Internett, og opphavsrettstvister har ingenting med dette nettstedet å gjøre. Du må fullstendig slette innholdet ovenfor fra datamaskinen din innen 24 timer etter nedlasting. Hvis du liker programmet, vennligst støtt ekte programvare, kjøp registrering, og få bedre ekte tjenester. Hvis det foreligger noen krenkelse, vennligst kontakt oss på e-post.

Mail To:help@itsvse.com