ValueTaskT
suggest changeTask<T>
is a class and causes the unnecessary overhead of its allocation when the result is immediately available.
ValueTask<T>
is a structure and has been introduced to prevent the allocation of a Task
object in case the result of the async operation is already available at the time of awaiting.
So ValueTask<T>
provides two benefits:
1. Performance increase
Here’s a Task<T>
example:
- Requires heap allocation
- Takes 120ns with JIT
async Task<int> TestTask(int d)
{
await Task.Delay(d);
return 10;
}
Here’s the analog ValueTask<T>
example:
- No heap allocation if the result is known synchronously (which it is not in this case because of the
Task.Delay
, but often is in many real-worldasync
/await
scenarios) - Takes 65ns with JIT
async ValueTask<int> TestValueTask(int d)
{
await Task.Delay(d);
return 10;
}
2. Increased implementation flexibility
Implementations of an async interface wishing to be synchronous would otherwise be forced to use either Task.Run
or Task.FromResult
(resulting in the performance penalty discussed above). Thus there’s some pressure against synchronous implementations.
But with ValueTask<T>
, implementations are more free to choose between being synchronous or asynchronous without impacting callers.
For example, here’s an interface with an asynchronous method:
interface IFoo<T>
{
ValueTask<T> BarAsync();
}
…and here’s how that method might be called:
IFoo<T> thing = getThing();
var x = await thing.BarAsync();
With ValueTask
, the above code will work with either synchronous or asynchronous implementations:
Synchronous implementation:
class SynchronousFoo<T> : IFoo<T>
{
public ValueTask<T> BarAsync()
{
var value = default(T);
return new ValueTask<T>(value);
}
}
Asynchronous implementation
class AsynchronousFoo<T> : IFoo<T>
{
public async ValueTask<T> BarAsync()
{
var value = default(T);
await Task.Delay(1);
return value;
}
}
Notes
Although ValueTask
struct was being planned to be added to C# 7.0, it has been kept as another library for the time being. http://stackoverflow.com/documentation/c%23/1936/c-sharp-7-0-features/28612/valuetaskt# System.Threading.Tasks.Extensions
package can be downloaded from Nuget Gallery