Explicación ValueTask en C#

17 Mar 2025 5 min (0) Comentarios

Desde 2018 con la llegada de C# 8 tenemos un tipo que se llama ValueTask el cual puede reemplazar en ciertos escenarios al tipo Task que lleva en el lenguaje desde 2005. Sin embargo lo más probable es que no utilices dicho tipo, ahora veremos el por qué. 

 

 

1 - Cuándo utilizar ValueTask?

 

Quiero empezar por la conclusión. Cuándo vamos a utilizar ValueTask<T>? En este caso, o mejor dicho está clase tiene un escenario principal en mente.

Este supuesto es cuando tenemos múltiples implementaciones de un mismo método donde la mayoría se completan de forma síncrona.

 

Por ejemplo, tienes una interfaz con 10 implementaciones de dicha interfaz, donde 7 u 8 se completan de forma síncrona. En ese caso, utilizamos ValueTask<T>, si por ejemplo las 10 o 9 o incluso 5 se completan de forma asíncrona utilizaremos Task. 

Esto quiere decir que no tienes que migrar todo tu código para utilizar ValueTask, utilizar Task está igual de bien. 

Relacionado con el caso anterior tenemos el caso de los hot paths, un hot path es una parte del código que se ejecuta frecuentemente, si este hot path es síncrono, también es recomendable utilizar ValueTask<T>, un escenario es si tenemos 10 implementaciones y de esas 10 una se llama el 95% de las veces y es síncrona, en ese caso, esta implementación sería el hot path. 

public interface IImplementation
{
    public ValueTask<int> GetValue();
}

public class DefaultImplementation : IImplementation
{
    public ValueTask<int> GetValue()
    {
        return new ValueTask<int>(1);
    }
}

public class D1Implementation : IImplementation
{
    
    public async ValueTask<int> GetValue()
    {
        return await _dependency.GetValue(); //Simulates 3rd party implementation.
    }
}

public class D2Implementation : IImplementation
{
    
    public async ValueTask<int> GetValue()
    {
        return await _dependency.GetValue(); //Simulates 3rd party implementation.
    }
}

Debido a cómo funciona ValueTask por detrás, no crea un nuevo objeto Task lo que reduce la carga del garbage collector y el uso de memoria.  Lo cual siempre está bien.

 

Para el resto de escenarios, utiliza Task.

 

 

2 - Advertencias en el uso de ValueTasks

Técniamente ValueTask es un union Type de Task y de T lo que implica que se puede consumir una única vez.

Vamos que este código no se debe hacer:

ValueTask<int> response = implementation.GetValue();

int value1 = await response;
int value2 = await response;

Porque lo más posible es que si lo haces te salte una excepción ya que una vez haces el await del ValueTask el objeto se recicla y causará problemas. 

 

Mientras que si usas task es posible hacer await múltiples veces sin que el código se rompa.

 

Es importante recordar que ValueTask es una estructura (struct), lo que significa que estamos trabajando con un tipo por valor y todo lo que eso implica. En cambio, Task es un tipo por referencia con solo un campo interno. ¿Por qué importa esto? Porque cuando usamos ValueTask, tenemos más datos que gestionar y más detalles a los que prestar atención. Ya que en algunos escenarios puede afectar el tamaño y rendimiento del código generado en algunos casos.

 

Por norma general lo suyo es utilizar task, pero si vas a utilizar ValueTask lo recomendable es correr varios benchmarks para asegurarnos que es lo más recomendable en nuestro escenario.

 

 

3 - Debo utilizar Task o ValueTask?

 

Si te te estas haciendo esta pregunta la respuesta es muy sencilla, utiliza Task. Uno de los motivos principales por los que se introduzco ValueTask fue para leer Streams de datos con un un volumen extremo, donde muy comunmente no son asyncronos debido al buffer. SI lo que estas construyendo es una API o una app simple que accede a los valores de una base de datos también utilzia Task porque el uso de ValueTask no te proporciona ningún beneficio mas alla del coste del recolector de basura con la Task, lo que es un coste ridículo, incluso con millones de Tasks. 

 

Uso del bloqueador de anuncios adblock

Hola!

Primero de todo bienvenido a la web de NetMentor donde podrás aprender programación en C# y .NET desde un nivel de principiante hasta más avanzado.


Yo entiendo que utilices un bloqueador de anuncios como AdBlock, Ublock o el propio navegador Brave. Pero te tengo que pedir por favor que desactives el bloqueador para esta web.


Intento personalmente no poner mucha publicidad, la justa para pagar el servidor y por supuesto que no sea intrusiva; Si pese a ello piensas que es intrusiva siempre me puedes escribir por privado o por Twitter a @NetMentorTW.


Si ya lo has desactivado, por favor recarga la página.


Un saludo y muchas gracias por tu colaboración

© copyright 2025 NetMentor | Todos los derechos reservados | RSS Feed

Buy me a coffee Invitame a un café