Questo articolo è un articolo speculare di traduzione automatica, clicca qui per saltare all'articolo originale.

Vista: 42759|Risposta: 5

[Fonte] Perché il compito .net/c# è più lento di Thread?

[Copiato link]
Pubblicato su 03/05/2017 16:40:28 | | | |
.NET 4 include un nuovo namespace, System.Threading.Tasks, che contiene classi che astraiscono la funzionalità di threading. Usa ThreadPool in background. Un compito rappresenta il lavoro di un'unità che deve essere completata. Il lavoro di questa unità può essere eseguito in un thread separato oppure un compito può essere avviato in sincrono, il che richiede di attendere il thread principale di accordo. Usare i task non solo ti dà un livello di astrazione, ma anche molto controllo sui thread sottostanti.
I compiti offrono molta flessibilità quando si tratta di programmare il lavoro da svolgere. Ad esempio, puoi definire un compito continuo – quale lavoro dovrebbe essere svolto dopo che un compito è stato completato. Questo può fare la differenza tra un compito riuscito e uno meno. Inoltre, i compiti possono essere organizzati in una gerarchia. Ad esempio, un task genitore può creare un nuovo task figlio. Questo crea una dipendenza in modo che, se annulli il task genitore, anche il suo task figlio verrà annullato.


Oggi è popolare usare metodi di esecuzione dei compiti, ed è ad alte prestazioni, e non so dove siano le prestazioni del compito.

Ho testato personalmente Task e Thread, e ho la sensazione che Task sia molto lenta, il che influisce molto sulle prestazioni, e il codice di test è il seguente:

Ripetiamo il metodo 1000 volte, poi il metodo blocca per 100 millisecondi, e il risultato del test è il seguente:



Risultato:
L'esecuzione del thread richiede 188 millisecondi
L'esecuzione del compito richiede 14.671 millisecondi


La differenza di velocità tra i due è di 78 volte!!

Il compito è molto lento, non so perché succeda, c'è qualcosa che non va nel mio codice di test o cosa? Spero tu possa spiegare perché succede...




Precedente:Invia messaggi con ASP.NET Core
Prossimo:C# Calcolo Parallelo Parallelo.For&Parallel.For
 Padrone di casa| Pubblicato su 13/10/2020 10:47:17 |
tongli1996218 Pubblicato il 13-10-2020 alle 09:34
Per garantire lo stesso codice di Thread, la mia operazione è il seguente codice, e quanto sopra è pseudo-codice
PS: Chiama e attendi il compito. Ritardi senza aggiungere ...

Sì, grazie

Tempo di esecuzione del compito: 117.0357

Puoi modificare il codice come segue:

Task.Run sostituisce Task.Factory.StartNew perché discompila automaticamente i compiti interni.
Task.WaitAll aspetta un compito esterno invece che interno. L'uso di Task.Run non ha task annidate.


Guardando la documentazione msdn, puoi vedere che il metodo Task.Delay Method crea un compito che si completa dopo un numero specificato di millisecondi. (In effetti, verrà creato un nuovo thread e verrà aggiunto await per aspettare che il compito venga eseguito, non so se ho capito bene)

Il login del link ipertestuale è visibile.

Inoltre, c'è una differenza tra compito e vuoto

Il compito restituisce un metodo asincrono che può aspettare
Il metodo void return asincrono non può aspettare, funziona in modo asincrono, non puoi sapere quando è finito, non puoi monitorare lo stato di quell'operazione asincrona.


Riferimento:

Il login del link ipertestuale è visibile.
Il login del link ipertestuale è visibile.

In sintesi: c'è un problema con il codice, non dovrei usare Thread.Sleep all'interno del metodo Task
Pubblicato su 21/07/2020 13:09:29 |
Ho avuto lo stesso problema oggi, usando il multithreading per la crittografia AES, Task è molto più lento di Thread!!
Il proprietario ha trovato il motivo?
Pubblicato su 12/10/2020 19:24:48 |
Questo post è stato modificato l'ultima volta da tongli1996218 il 12-10-2020 alle 19:43

Dopo aver testato il codice del proprietario, quando il programma viene avviato ed eseguito più volte, il tempo del compito continua a diminuire, e sul mio computer si riduce a meno di Thread, e Thread resta stabile entro questo tempo.

Successivamente si scoprì che il metodo Thread.Sleep(100) aveva un impatto negativo sul Task, ma non su Thread, e Thread.Sleep(100) poteva essere sostituito con altre verifiche di programma che richiedevano molto tempo, come l'auto-addizione numerica o await Task.Delay(100).

PS: Thread.Sleep terminerà il tempo di slicing corrente del thread dopo aver chiamato, ad esempio Thread.Sleep(0) terminerà il tempo di slicing corrente del thread e lo trasferirà ad altri thread per essere eseguiti. All'interno del task c'è un pool di thread, che può ottimizzare il cambio di contesto dei thread e ridurre i tempi di perdita di CPU (soprattutto per l'ottimizzazione multi-core), mentre Thread.Sleep(100) interrompe la logica di switching del pool thread originale del task, causando una notevole perdita di tempo di CPU

Se sostituisci Thread.Sleep(100) con await Task.Delay(100), scoprirai che il tempo consumato dal task è solo superiore a 100 millisecondi, come mostrato di seguito:
privato void TaskTest()
{
        Filo.Sonno(100);
         ... Esegui l'azione
}
Sostituito da
privato async void TaskTest()
{
      attende compito. Ritardo (100);
      ... L'esecuzione richiede più di 100 millisecondi per il compito, che corrisponde allo Thread.Sleep(100) originale per Thread
}




 Padrone di casa| Pubblicato su 12/10/2020 22:53:05 |
tongli1996218 Pubblicato il 2020-10-12 19:24
Dopo aver testato il codice del proprietario, quando il programma viene avviato, il tempo del compito continua a diminuire dopo l'esecuzione più volte, e sul mio computer si riduce a meno di Thread...

Ho provato a cambiarlo in codice così:
Compito.Ritardo (100000);

Tempo di esecuzione del compito:14,1306 ms, il tempo totale è effettivamente molto breve, tuttavia ho notato che il metodo chiamato da Task non completava l'esecuzione.
Pubblicato su 13/10/2020 09:34:33 |
Questo post è stato modificato l'ultima volta da tongli1996218 il 13-10-2020 alle 09:40
Pubblicato il 12-10-2020 alle 22:53
Ho provato a cambiarlo in codice così:
Compito.Ritardo (100000);

Per garantire lo stesso codice di Thread, la mia operazione è il seguente codice, e quanto sopra è pseudo-codice
PS: basta chiamare await Task.Delay, poi aggiungere nessun codice, il thread aperto dal task viene restituito immediatamente, per garantire la simulazione del compute-bound, puoi usare per (int a = 0; a< 1000000; ++a){}; Tali metodi invece

TaskTest() privato async static void
        {
            attende compito. Ritardo(100000);
             Interbloccata. Incremento (riferimento);    Bloccatura, ma la testa superiore è più piccola
            if(run == j)
             {
                Cronometro. Stop(); Fermate il monitoraggio
                TimeSpan time = cronometro. È passato;  Ottiene il tempo totale misurato dall'istanza corrente
                Console.WriteLine("Task execution time:" + timespan. TotalMillisecond); Millisecondi totali
              }
        Il tempo impiegato è anche molto breve


Disconoscimento:
Tutto il software, i materiali di programmazione o gli articoli pubblicati dalla Code Farmer Network sono destinati esclusivamente all'apprendimento e alla ricerca; I contenuti sopra elencati non devono essere utilizzati per scopi commerciali o illegali, altrimenti gli utenti dovranno sostenere tutte le conseguenze. Le informazioni su questo sito provengono da Internet, e le controversie sul copyright non hanno nulla a che fare con questo sito. Devi eliminare completamente i contenuti sopra elencati dal tuo computer entro 24 ore dal download. Se ti piace il programma, ti preghiamo di supportare software autentico, acquistare la registrazione e ottenere servizi autentici migliori. In caso di violazione, vi preghiamo di contattarci via email.

Mail To:help@itsvse.com