Day 20 of 30-Day .NET Challenge: Task vs. ValueTask
Tags: dotnet, aspnet, csharp, programming
Published: 2024-04-08 07:38:00

Heap allocations aren’t entirely bad but when an object is allocated on a heap it contributes to the garbage collection cycles which in turn reduces overall application performance.


## Introduction

One approach  to optimize resource usage in async code is by using ValueTask<TResult> syntax to minimize heap allocations, which in turn reduces pressure on garbage collection and enhances overall performance.

### Learning Objectives

* The Problem with Heap Allocations

* Optimizing with ValueTask<TResult>

* When to Use ValueTask<TResult>

### Prerequisites for Developers

* Basic understanding of C# programming language.

## Getting Started

Heap allocations aren’t entirely bad but when an object is allocated on a heap it contributes to the garbage collection cycles which in turn reduces overall application performance. In case of excessive heap allocation, the garbage collector can lead to GC pauses.

### Bad Practice: Excessive Use of Task<TResult>

Let’s consider a common asynchronous pattern that developers commonly use:
```csharp
    public async Task<string> ReadDataAsync()
    {
        var data = await ReadFromStreamAsync(_stream);
        return ProcessData(data);
    }
```
If the above-mentioned method is called more frequently, each request results in a new Task instance being allocated on heap memory. Over time, it leads to increased garbage collection overhead.

### Optimizing with ValueTask<TResult>

By changing the return type from Task<TResult> to ValueTask<TResult>, we can reduce heap allocations
```csharp
    public async ValueTask<string> ReadDataAsync()
    {
        var data = await ReadFromStreamAsync(_stream);
        return ProcessData(data);
    }
```
The aforementioned optimization is beneficial for high-frequency async operations or methods which are expected to complete synchronously in a significant portion of time.

### When to Use ValueTask<TResult>

* High-frequency methods

* Performance-sensitive code

* Methods that often complete synchronously

Create another class named TaskVsValueTask and add the following code snippet
```csharp
    public static class TaskVsValueTask
    {
        public static async Task<string> FetchDataAsync()
        {
            // Simulate a delay to mimic fetching data
            await Task.Delay(1000);
            return "Data fetched using Task";
        }
    
        public static async ValueTask<string> FetchDataValueTaskAsync()
        {
            // Simulate a delay to mimic fetching data
            await Task.Delay(1000); // Note: Use Task.Delay for the sake of example.
            return "Data fetched using ValueTask";
        }
    }
```
Execute from the main method as follows
```csharp
    #region Day 20: Task vs. Value Task
    static async Task<string> ExecuteDay20()
    {
        Console.WriteLine("Fetching data with Task...");
        string result = await TaskVsValueTask.FetchDataAsync();
        Console.WriteLine(result);
    
        Console.WriteLine("Fetching data with ValueTask...");
        string resultValueTask = await TaskVsValueTask.FetchDataValueTaskAsync();
        Console.WriteLine(resultValueTask);
    
        return "Executed Day 20 successfully..!!";
    }
    #endregion
```
Console Output
```
    Fetching data with Task...
    Data fetched using Task
    Fetching data with ValueTask...
    Data fetched using ValueTask
```
## Complete Code on GitHub
[GitHub — ssukhpinder/30DayChallenge.Net](https://github.com/ssukhpinder/30DayChallenge.Net/tree/main)

### C# Programming🚀

Thank you for being a part of the C# community! Before you leave:

Follow us: [Youtube](https://www.youtube.com/channel/UCejYGg4gAOa1uPAObFuk1HQ) | [X](https://twitter.com/sukhsukhpinder) | [LinkedIn](https://www.linkedin.com/in/sukhpinder-singh/) | [Dev.to](https://dev.to/ssukhpinder) 
Visit our other platforms: [GitHub](https://github.com/ssukhpinder) 
More content at [C# Programming](https://medium.com/c-sharp-progarmming)