简体   繁体   中英

How should I convert a function returning a non-generic Task to ValueTask?

I'm working on some code which builds a buffer in memory and then empties it into a TextWriter when the buffer fills up. Most of the time, the character will go straight into the buffer (synchronously) but occasionally (once every 4kb) I need to call TextWriter.WriteAsync .

In the System.Threading.Tasks.Extensions package there only appears to be a ValueTask<T> struct, and no non-generic ValueTask (without a type parameter). Why is there no ValueTask , and what should I do if I need to convert a method returning a non-generic Task (that is, the async equivalent of a void method) to ValueTask ?

Shot in the dark, but I think it's because Task.CompletedTask is sufficient for most non-generic cases.

One way to think of ValueTask<T> is as a union of Task<T> and T (for asynchronous and synchronous cases respectively). Accordingly a non-generic ValueTask would be a union of Task and... nothing, so just a Task .

I can't think of a case where a non-generic ValueTask would be practically different than caching an already completed Task (which is what Task.CompletedTask is), though I'd love to learn about any.

Based on this article , you can change any asynchronous method directly from Task to ValueTask , but you must beware of its usage patterns mentioned in the article; specifically:

  • Awaiting the instance multiple times.
  • Calling AsTask multiple times.
  • Using more than one of these techniques to consume the instance.

And if you need to get the result back as a Task / Task<TResult> , you should use .AsTask() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM