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

Vista: 15343|Resposta: 2

[Comunicação] [Tradução]. NET para usar a diferença entre ValueTask e Task

[Copiar link]
Postado em 17-03-2022 às 11:21:50 | | | |


Usar classes de Tarefa ou Tarefa tem um gargalo de desempenho que não mencionamos em artigos anteriores. Resumindo, essas aulas lideram quando os resultados estão imediatamente disponíveisAlocação desnecessária。 Isso significa que uma nova Tarefa ou objeto Tarefa sempre será criada, mesmo que o resultado já esteja disponível. Agora, mencionamos que o conceito de async/await que usamos em artigos anteriores existe desde o lançamento do .NET 4.5. Esse recurso foi aprimorado desde C#7 com a versão .NET 4.7, com a estrutura ValueTask, que pode ser usada como retorno para funções assíncronas.

Estrutura ValueTask


A estrutura ValueTask apareceu pela primeira vez no repositório corefxlab em 2015. Este repositório é usado para experimentar e explorar novas ideias que podem ou não chegar ao repositório principal corefx. O repositório Corefx é o repositório onde todas as bibliotecas base do .NET Core estão localizadas. Foi desenvolvido e sugerido por Stephen Taub para a biblioteca System.Threading.Tasks.Channels. Naquele momento, Stephen deu uma breve explicação:

Endereço da biblioteca CorefxLab:O login do hiperlink está visível.


Um ValueTask é uma união distinta de um T e uma Tarefa, permitindo que o ReadAsync aloque livremente para retornar sincronamente seus valores T disponíveis (ao contrário do uso do Task.FromResult, que requer a alocação de uma instância de Task). O ValueTask é aguardável, então o consumo da maioria das instâncias é indistinguível do consumo das tarefas.
Muitas pessoas veem os benefícios de usar essa estrutura, que está incluída em C# 7 como parte do pacote NuGet System.Threading.Tasks.Extensions. Então, antes de mergulharmos na estrutura ValueTask, vamos examinar o problema que ela usa para resolver. Como Tarefa(Tarefa) é um tipo de referência, comece comO método assíncrono que retorna o objeto Tarefa significa que ele é alocado no heap toda vez。 Isso é necessário em muitos casos.

No entanto, em alguns casos, métodos assíncronos retornam resultados imediatamente ou completam de forma síncrona. Nesses casos, essa alocação é desnecessária e pode se tornar cara em partes críticas de desempenho do código. Até o lançamento do .NET 4.7, não havia como evitar isso, pois métodos assíncronos precisavam retornar Tarefa, <T>Tarefa ou void (a última geralmente era indesejável). Nesta versão do .NET, isso é estendido, o que significa que um método assíncrono pode retornar qualquer tipo, desde que tenha um método GetAwaiter acessível. ValueTask é um exemplo concreto desse tipo, e também foi adicionado a esta versão.

Você pode navegar pelo repositório corefx e ver a implementação completa do ValueTask, aqui está a seção da API que nos interessa:



Como estrutura, o ValueTask permite escrever métodos assíncronos que não alocam memória durante o tempo de execução síncrono. A consistência da API do conceito de async/await não é comprometida dessa forma. Além disso, essa estrutura espera sozinha, tornando-a fácil de usar. Por exemplo, se executarmos este código simples:

No método MultiplyAsync, estamos simulando uma situação em que queremos evitar usar Tarefa e retornar apenas um inteiro simples. Isso é feito na instrução if do método, onde basicamente verificamos se o parâmetro passado é zero. O problema éMesmo que nossa condição na instrução if seja verdadeira, o código acima cria um objeto Task。 Resolvemos esse problema assim:

ValorTarefa e Tarefa



Como mencionado anteriormente, existem dois benefícios principais em usar o ValueTask:

  • Melhorias de desempenho
  • Aumentar a flexibilidade da implementação


Então, quais são os números por trás das melhorias de desempenho? Observe este código:


Se executarmos esse código, leva 120ns para executar o JIT. Agora, se substituírmos Tarefa por ValorTarefa assim:

Com o JIT, teremos um tempo de execução de 65ns. Agora, é verdade que, devido ao Task.Delay, não estamos executando de forma síncrona, mas vemos uma melhora no tempo de execução.

Outro benefício que mencionamos é a maior flexibilidade na implementação. Agora, o que exatamente isso significa? Bem, implementações de interfaces assíncronas que deveriam ser sincronizadas serão forçadas a usar Task.Run ou Task.FromResult. Claro, isso leva aos problemas de desempenho que discutimos anteriormente. Quando usamos o ValueTask, é mais provável que escolhamos entre implementações síncronas ou assíncronas. Lembre-se de que isso pode ser um sinal de que seu código pode não ser bem elaborado se isso acontecer com você.

Por exemplo, observe esta interface:


Vamos supor que você queira chamá-lo a partir de um código assim:

Como usamos o ValueTask na interface, a implementação da interface pode ser síncrona ou assíncrona. Podemos obter esse benefício basicamente pulando a adição de algumas funções ao IT que lidam com o comportamento de sincronização. É muito mais fácil usar essa interface dessa forma. Aqui está uma implementação síncrona da interface acima:

Aqui está uma implementação assíncrona da mesma interface:

No entanto, devemos considerar algumas desvantagens antes de usar o ValueTask. É fácil pensar que ValueTask deveria ser usado por padrão em vez de Task, o que certamente não é o caso. Por exemplo, embora o ValueTask nos ajude a evitar atribuições desnecessárias quando a sincronização de resultados está disponível, ele também contém dois campos.

É importante lembrar que essa é a estrutura que estamos usando aqui, o que significa que estamos usando tipos de valor e todos os seus encargos. Tarefa, por outro lado, é um tipo de referência com apenas um campo.Quando você usa o ValueTask, temos mais dados para processar e processar. Se tal método for esperado em um método assíncrono, então o método assíncrono éA máquina de estados também será maior, porque armazenar toda a estrutura geralmente requer mais espaço do que armazenar uma única referência.

Por isso, o pessoal da Microsoft realmente recomenda usar Tarefa ou Tarefa como tipo padrão de retorno para métodos assíncronos. Somente após a análise de desempenho você deve considerar a mudança para o ValueTask.


resumo

ValueTask é uma estrutura introduzida no .NET 4.7 que nos oferece muitas possibilidades para usar métodos assíncronos no .NET. No entanto, não é sem um preço. Isso é útil para métodos críticos de desempenho que são executados de forma síncrona. Com eles, podemos evitar atribuir objetos desnecessários. Ainda assim, como tipo valor, ele traz todos os problemas que os tipos de valor geralmente têm. Portanto, podemos nos beneficiar dessa estrutura, mas precisamos ter cuidado.

Endereço original:O login do hiperlink está visível.




Anterior:【Ação Prática】Use o Docker para construir um servidor VPN IPsec
Próximo:Escolha o OpenConnect em vez do Cisco AnyConnect para evitar roteamento de bloqueios de tabela
Postado em 18-03-2022 22:21:57 |
Venha aprender de novo.
Postado em 2022-03-22 14:05:53 |
Aprenda a essência do aprendizadoNada mau
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