Dit artikel is een spiegelartikel van machinevertaling, klik hier om naar het oorspronkelijke artikel te gaan.

Bekijken: 42759|Antwoord: 5

[Bron] Waarom is .net/c# Task trager dan Thread?

[Link kopiëren]
Geplaatst op 03-05-2017 16:40:28 | | | |
.NET 4 bevat een nieuwe naamruimte, System.Threading.Tasks, die klassen bevat die threadingfunctionaliteit abstraheren. Gebruik ThreadPool op de achtergrond. Een taak vertegenwoordigt het werk van een eenheid die voltooid moet worden. Het werk van deze eenheid kan in een aparte thread worden uitgevoerd of een taak kan synchroon worden gestart, wat wachten vereist op de hoofd-tuning thread. Het gebruik van taken geeft je niet alleen een abstractielaag, maar ook veel controle over de onderliggende threads.
Taken bieden veel flexibiliteit bij het plannen van het werk dat gedaan moet worden. Je kunt bijvoorbeeld een continue taak definiëren – welk werk er moet worden gedaan nadat een taak is voltooid. Dit kan het verschil maken tussen een succesvolle klus en niet. Daarnaast kunnen taken in een hiërarchie worden gerangschikt. Bijvoorbeeld, een oudertaak kan een nieuwe kindtaak aanmaken. Dit creëert een afhankelijkheid zodat als je de oudertaak annuleert, ook de kindtaak wordt geannuleerd.


Tegenwoordig is het populair om taakuitvoeringsmethoden te gebruiken, en het levert hoge prestaties op, en ik weet niet waar de taakprestaties zijn.

Ik heb Task en Thread zelf getest, en ik vind dat Task erg traag is, wat de prestaties sterk beïnvloedt, en de testcode is als volgt:

We lopen de methode 1000 keer in een lus, waarna de methode 100 milliseconden blokkeert, en het testresultaat is als volgt:



Resultaat:
De uitvoering van de thread duurt 188 milliseconden
De uitvoering van de taak duurt 14.671 milliseconden


Het snelheidsverschil tussen de twee is 78 keer zo groot!!

De taak is erg traag, ik weet niet waarom dit gebeurt, is er iets mis met mijn testcode, of wat? Ik hoop dat je kunt uitleggen waarom dit gebeurt...




Vorig:Stuur berichten met ASP.NET Core
Volgend:C# Parallelle berekening Parallel.For&Parallel.For
 Huisbaas| Geplaatst op 13-10-2020 10:47:17 |
tongli1996218 Geplaatst op 2020-10-13 09:34
Om dezelfde code als Thread te garanderen, is mijn bewerking de volgende code, en bovenstaande is pseudocode
PS: Roep gewoon await Task.Delay aan zonder toe te voegen ...

Ja, bedankt

Taakuitvoeringstijd: 117.0357

Je kunt de code als volgt aanpassen:

Task.Run vervangt Task.Factory.StartNew omdat het automatisch interne taken uitpakt.
Task.WaitAll wacht op een externe taak in plaats van een interne. Het gebruik van Task.Run heeft geen geneste taken.


Als je naar de msdn-documentatie kijkt, zie je dat de Task.Delay-methode een taak aanmaakt die na een bepaald aantal milliseconden wordt voltooid. (Sterker nog, er wordt een nieuwe thread aangemaakt en wordt er wacht toegevoegd om te wachten tot de taak wordt uitgevoerd, ik weet niet of ik het goed begrijp)

De hyperlink-login is zichtbaar.

Daarnaast is er een verschil tussen Task en void

Task geeft een asynchrone methode terug die kan wachten
De void return asynchrone methode kan niet wachten, het werkt asynchroon, je kunt niet weten wanneer het klaar is, je kunt de status van die asynchrone bewerking niet monitoren.


Referentie:

De hyperlink-login is zichtbaar.
De hyperlink-login is zichtbaar.

Samengevat: er is een probleem met de code, ik zou Thread.Sleep niet moeten gebruiken binnen de Task-methode
Geplaatst op 21-07-2020 13:09:29 |
Ik had vandaag hetzelfde probleem, ik gebruikte multithreading voor AES-encryptie, Task is veel trager dan Thread!!
Heeft de verhuurder de reden gevonden?
Geplaatst op 12-10-2020 19:24:48 |
Dit bericht is voor het laatst bewerkt door tongli1996218 op 2020-10-12 19:43

Na het testen van de code van de eigenaar, wanneer het programma meerdere keren wordt gestart en uitgevoerd, blijft de taaktijd afnemen, en op mijn computer wordt deze teruggebracht tot minder dan Thread, en Thread is stabiel binnen deze tijd.

Later bleek dat de Thread.Sleep(100)-methode een negatieve invloed had op Task, maar niet op Thread, en Thread.Sleep(100) kon worden vervangen door andere tijdrovende programmaverificatie zoals numerieke zelfoptelling of wachten op Task.Delay(100).

PS: Thread.Sleep beëindigt de huidige thread-slicingtijd na het aanroepen, zoals Thread.Sleep(0) zal de huidige thread-slicingtijd beëindigen en deze overzetten naar andere threads om uit te voeren. Binnen de taak bevindt zich een threadpool, die het contextwisselen van threads kan optimaliseren en CPU-verliestijd kan verminderen (vooral voor multi-core CPU-optimalisatie), terwijl Thread.Sleep(100) de schakellogica van de oorspronkelijke threadpool van de taak zal verstoren, wat veel CPU-tijdverlies veroorzaakt

Als je Thread.Sleep(100) vervangt door await Task.Delay(100), zul je merken dat de tijdsinvestering van de taak slechts meer dan 100 milliseconden is, zoals hieronder weergegeven:
private void TaskTest()
{
        Thread.Sleep(100);
         ... Voer de actie uit
}
Vervangen door
private async void TaskTest()
{
      wachten op Task.Delay(100);
      ... De uitvoering duurt meer dan 100 milliseconden voor de taak, wat hetzelfde is als de originele Thread.Sleep(100) voor Thread
}




 Huisbaas| Geplaatst op 12-10-2020 22:53:05 |
tongli1996218 Geplaatst op 2020-10-12 19:24
Na het testen van de code van de eigenaar, wanneer het programma wordt gestart, blijft de tijd van de taak afnemen na meerdere keren uitvoeren, en op mijn computer wordt deze verminderd tot minder dan Thread...

Ik heb geprobeerd het te veranderen naar code als volgt:
Taak.Vertraging(100000);

Taakuitvoeringstijd:14,1306 ms, de totale tijd is inderdaad erg kort, maar ik ontdekte dat de methode die door Task werd aangeroepen de uitvoering niet voltooide.
Geplaatst op 13-10-2020 09:34:33 |
Dit bericht is voor het laatst bewerkt door tongli1996218 op 13-10-2020 09:40
Gepubliceerd op 12-10-2020 22:53
Ik heb geprobeerd het te veranderen naar code als volgt:
Taak.Vertraging(100000);

Om dezelfde code als Thread te garanderen, is mijn bewerking de volgende code, en bovenstaande is pseudocode
PS: Roep gewoon await Task.Delay aan en voeg dan geen code toe, de thread die door de taak wordt geopend wordt direct teruggegeven, om de simulatie van compute-bound te garanderen, kun je gebruiken voor (int a = 0; a< 1000000; ++a){}; Dergelijke methoden in plaats daarvan

private asynchrone statische void TaskTest()
        {
            wachten op Task.Delay(100000);
             Interlocked.Increment (ref run);    Vergrendeling, maar de bovenkant is kleiner
            als(run == j)
             {
                Stopwatch. Stop(); Stop met monitoren
                Timespan timespan = stopwatch. Verstreken;  Krijgt de totale tijd die door de huidige instantie wordt gemeten
                Console.WriteLine("Taakuitvoeringstijd:" + tijdspanne. TotalMilliseconds); Totale milliseconden
              }
        De tijd die wordt besteed is ook erg kort


Disclaimer:
Alle software, programmeermaterialen of artikelen die door Code Farmer Network worden gepubliceerd, zijn uitsluitend bedoeld voor leer- en onderzoeksdoeleinden; De bovenstaande inhoud mag niet worden gebruikt voor commerciële of illegale doeleinden, anders dragen gebruikers alle gevolgen. De informatie op deze site komt van het internet, en auteursrechtconflicten hebben niets met deze site te maken. Je moet bovenstaande inhoud volledig van je computer verwijderen binnen 24 uur na het downloaden. Als je het programma leuk vindt, steun dan de echte software, koop registratie en krijg betere echte diensten. Als er sprake is van een inbreuk, neem dan contact met ons op via e-mail.

Mail To:help@itsvse.com