• Jobs
  • About Us
  • professionals
    • Home
    • Jobs
    • Courses and challenges
  • business
    • Home
    • Post vacancy
    • Our process
    • Pricing
    • Assessments
    • Payroll
    • Blog
    • Sales
    • Salary Calculator

0

312
Views
¿Cuál es el punto de ValueTask.Preserve()?

ValueTask y ValueTask<TResult> tienen un método Preserve() que se resume como "Obtiene una ValueTask que se puede usar en cualquier momento en el futuro".

¿Qué significa eso y cuándo debemos usarlo? ¿Significa que una ValueTask 'normal' no se puede usar "en ningún momento en el futuro"? Si es así, ¿por qué?

over 3 years ago · Santiago Trujillo
2 answers
Answer question

0

La documentación no es muy clara. De la fuente :

 /// <summary>null if representing a successful synchronous completion, /// otherwise a <see cref="Task"/> or a <see cref="IValueTaskSource"/>.</summary> internal readonly object? _obj;

ValueTask declara internamente un objeto contenedor anulable para contener la Task o IValueTaskSource que ValueTask encapsula en caso de que sea un ValueTask que lo haga. De lo contrario, es null si ValueTask representa una finalización.

 public ValueTask Preserve() => _obj == null ? this : new ValueTask(AsTask());

Preserve() devuelve una nueva ValueTask representa su tarea subyacente en el caso de que ValueTask represente una Task o un IValueTaskSource (es decir: _obj != null ) o simplemente se devuelve a sí misma si ValueTask representa una finalización síncrona exitosa. Es necesario porque _obj es interno y no se puede probar externamente.

over 3 years ago · Santiago Trujillo Report

0

ValueTask es una optimización de rendimiento sobre Task s, pero este rendimiento tiene un costo: no puede usar ValueTask tan libremente como Task . La documentación menciona estas restricciones:

Las siguientes operaciones nunca deben realizarse en una instancia de ValueTask :

  • Esperando la instancia varias veces.
  • Llamando AsTask varias veces.
  • Usar más de una de estas técnicas para consumir la instancia.

Estas restricciones se aplican solo a las ValueTask respaldadas por un IValueTaskSource . Una ValueTask también puede estar respaldada por una Task o por un valor de TResult (para una ValueTask<TResult> ). Si sabe con 100 % de certeza que una ValueTask no está respaldada por un IValueTaskSource , puede usarla con la misma libertad que una Task . Por ejemplo, puede await varias veces, o puede esperar sincrónicamente para que se complete con .GetAwaiter().GetResult() .

En general, no sabe cómo se implementa internamente una ValueTask , e incluso si lo sabe (al estudiar el código fuente), es posible que no desee confiar en un detalle de implementación. Con el método ValueTask.Preserve , puede crear una nueva ValueTask que represente la ValueTask original y se puede usar sin restricciones porque no está creada por un IValueTaskSource . Este método afecta a la ValueTask original solo si está respaldada por un IValueTaskSource ; de lo contrario, no funciona (simplemente devuelve la tarea original sin cambios).

 ValueTask preserved = originalValueTask.Preserve();

Después de llamar a Preserve , se ha consumido la ValueTask original. Ya no debe esperarse, Preserve de nuevo ni convertirse en una Task con el método AsTask . Es probable que realizar cualquiera de esas acciones genere una InvalidOperationException . Pero ahora tiene la representación preserved de la misma, que se puede usar con la misma libertad que una Task .


Mi respuesta incluía inicialmente un ejemplo práctico del uso del método Preserve , que resultó ser incorrecto. Este ejemplo se puede encontrar en la cuarta revisión de esta respuesta.

over 3 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Our process Sales
Legal
Terms and conditions Privacy policy
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recommend me some offers
I have an error