Este artigo é um artigo espelhado de tradução automática, por favor clique aqui para ir para o artigo original.

Vista: 42759|Resposta: 5

[Fonte] Por que o .net/c# Task é mais lento que o Thread?

[Copiar link]
Publicado em 03/05/2017 16:40:28 | | | |
O .NET 4 inclui um novo namespace, System.Threading.Tasks, que contém classes que abstraem a funcionalidade de threading. Use o ThreadPool em segundo plano. Uma tarefa representa o trabalho de uma unidade que deve ser concluída. O trabalho dessa unidade pode ser executado em uma thread separada ou uma tarefa pode ser iniciada sincronizadamente, o que requer esperar pela thread principal de sintonia. Usar tarefas não só te dá uma camada de abstração, mas também muito controle sobre os threads subjacentes.
As tarefas oferecem muita flexibilidade na hora de agendar o trabalho que precisa ser feito. Por exemplo, você pode definir uma tarefa contínua – qual trabalho deve ser feito após a conclusão de uma tarefa. Isso pode fazer a diferença entre uma tarefa bem-sucedida e não. Além disso, as tarefas podem ser organizadas em uma hierarquia. Por exemplo, uma tarefa pai pode criar uma nova tarefa filha. Isso cria uma dependência para que, se você cancelar a tarefa pai, sua tarefa filha também será cancelada.


Hoje em dia, é comum usar métodos de execução de tarefas, e é de alto desempenho, e eu não sei onde está o desempenho das tarefas.

Eu mesmo testei Task and Thread, e sinto que Task é muito lento, o que afeta muito o desempenho, e o código de teste é o seguinte:

Passamos pelo método 1000 vezes, e então o método bloqueia por 100 milissegundos, e o resultado do teste é o seguinte:



Resultado:
A execução da thread leva 188 milissegundos
A execução da tarefa leva 14.671 milissegundos


A diferença de velocidade entre os dois é de 78 vezes!!

A tarefa está muito lenta, não sei por que isso está acontecendo, tem algo errado com meu código de teste, ou o quê? Espero que você consiga explicar por que isso acontece...




Anterior:Envie mensagens com ASP.NET Core
Próximo:C# Computação Paralela Paralela.Para&Paralela.Para
 Senhorio| Publicado em 13/10/2020 10:47:17 |
tongli1996218 Postado em 2020-10-13 09:34
Para garantir o mesmo código do Thread, minha operação é o seguinte, e o acima é pseudocódigo
PS: Apenas ligue aguardando a tarefa. Atrase sem adicionar ...

Sim, obrigado

Tempo de execução da tarefa: 117.0357

Você pode modificar o código da seguinte forma:

Task.Run substitui Task.Factory.StartNew porque desembala automaticamente as tarefas internas.
Task.WaitAll espera por uma tarefa externa em vez de uma interna. Usar o Task.Run não possui tarefas aninhadas.


Olhando a documentação da msdn, você pode ver que o método Task.Delay Method cria uma tarefa que é concluída após um número especificado de milissegundos. (Na verdade, uma nova thread será criada, e await será adicionado para esperar a tarefa ser executada, não sei se entendi direito)

O login do hiperlink está visível.

Além disso, há uma diferença entre Tarefa e Vazio

A tarefa retorna um método assíncrono que pode esperar
O método assíncrono de retorno de void não pode esperar, ele funciona de forma assíncrona, você não pode saber quando terminou, não pode monitorar o status dessa operação assíncrona.


Referência:

O login do hiperlink está visível.
O login do hiperlink está visível.

Resumindo: há um problema com o código, eu não deveria usar o Thread.Sleep dentro do método Task
Publicado em 21/07/2020 13:09:29 |
Tive o mesmo problema hoje, usando multithreading para criptografia AES, a Task é muito mais lenta que a Thread!!
O proprietário encontrou o motivo?
Publicado em 12/10/2020 19:24:48 |
Este post foi editado pela última vez por tongli1996218 em 2020-10-12 às 19:43

Depois de testar o código do dono, quando o programa é iniciado e executado várias vezes, o tempo da tarefa continua diminuindo, e no meu computador ele fica reduzido para menos que o Thread, e o Thread fica estável nesse período.

Posteriormente, descobriu-se que o método Thread.Sleep(100) tinha um impacto negativo na Tarefa, mas não na Thread, e o Thread.Sleep(100) podia ser substituído por outras verificações de programas demoradas, como auto-adição numérica ou await Task.Delay(100).

PS: Thread.Sleep encerra o tempo de fatiamento da thread atual após a chamada, como Thread.Sleep(0) encerra o tempo de fatiamento da thread atual e transfere para outras threads serem executadas. Dentro da tarefa há um pool de threads, que pode otimizar a troca de contexto das threads e reduzir o tempo de perda de CPU (especialmente para otimização multi-core de CPU), enquanto o Thread.Sleep(100) vai interromper a lógica de comutação do pool original de threads da tarefa, causando muita perda de tempo de CPU

Se você substituir Thread.Sleep(100) por await Task.Delay(100), verá que o consumo de tempo da tarefa é apenas mais de 100 milissegundos, como mostrado abaixo:
TaskTest() de void privado
{
        Thread.Sleep(100);
         ... Execute a ação
}
Substituído por
TaskTest() privado assíncrono void
{
      aguardando Tarefa. Atraso(100);
      ... A execução leva mais de 100 milissegundos para a tarefa, o que é o mesmo que o Thread.Sleep(100) original para o Thread
}




 Senhorio| Publicado em 12/10/2020 22:53:05 |
tongli1996218 Postado em 2020-10-12 19:24
Depois de testar o código do dono, quando o programa é iniciado, o tempo da tarefa continua diminuindo após várias execuções, e no meu computador ele é reduzido para menos que o Thread...

Tentei mudar para código assim:
Tarefa. Atraso(100000);

Tempo de execução da tarefa:14,1306 ms, o tempo total é realmente muito curto, porém, percebi que o método chamado por Tarefa não completou a execução.
Publicado em 13/10/2020 09:34:33 |
Este post foi editado pela última vez por tongli1996218 em 2020-10-13 às 09:40
Publicado em 2020-10-12 às 22:53
Tentei mudar para código assim:
Tarefa.Atraso (100000);

Para garantir o mesmo código do Thread, minha operação é o seguinte, e o acima é pseudocódigo
PS: Basta chamar await Task.Delay e então adicionar sem código, a thread aberta pela tarefa é retornada imediatamente, para garantir a simulação de compute-bound, você pode usar para (int a = 0; a< 1000000; ++a){}; Esses métodos em vez disso

TaskTest() estático privado assíncrono
        {
            aguardando Tarefa. Atraso(100000);
             Intertravado. Incremento (ref run);    Trava, mas o teto é menor
            if(run == j)
             {
                Cronometre. Stop(); Pare de monitorar
                TimeSpan tempo = cronômetro. Passou;  Obtém o tempo total medido pela instância atual
                Console.WriteLine("Tempo de execução da tarefa:" + período de tempo. Milissegundos Totais); Total de milissegundos
              }
        O tempo consumido também é muito curto


Disclaimer:
Todo software, material de programação ou artigos publicados pela Code Farmer Network são apenas para fins de aprendizado e pesquisa; O conteúdo acima não deve ser usado para fins comerciais ou ilegais, caso contrário, os usuários terão todas as consequências. As informações deste site vêm da Internet, e disputas de direitos autorais não têm nada a ver com este site. Você deve deletar completamente o conteúdo acima do seu computador em até 24 horas após o download. Se você gosta do programa, por favor, apoie um software genuíno, compre o registro e obtenha serviços genuínos melhores. Se houver qualquer infração, por favor, entre em contato conosco por e-mail.

Mail To:help@itsvse.com