Search code examples
c#async-awaitvaluetask

A ValueTask can be awaited only once - what does it mean?


I want to use ValueTask. I found somewhere that "a ValueTask can be awaited only once ". I cannot await for the method GetMoney multiple times or what? If yes, how should I change my code?

public class CreditCardService
{
    private Dictionary<int, int> _cache = new Dictionary<int, int>()
    {
        { 1, 500 },
        { 2, 600 }
    };

    public async ValueTask<int> GetMoney(int userId)
    {
        if (_cache.ContainsKey(userId))
        {
            return _cache[userId];
        }

        //some asynchronous operation:
        Random rnd = new Random();
        var money = rnd.Next(100);

        _cache[userId] = money;
        return await Task.FromResult(money);
    }
}

var creditCardService = new CreditCardService();
Console.WriteLine(await creditCardService.GetMoney(1));
Console.WriteLine(await creditCardService.GetMoney(3));
Console.WriteLine(await creditCardService.GetMoney(3));

Solution

  • You are awaiting each task exactly once:

    var creditCardService = new CreditCardService();
    Console.WriteLine(await creditCardService.GetMoney(1)); // a new ValueTask
    Console.WriteLine(await creditCardService.GetMoney(3)); // a new ValueTask
    Console.WriteLine(await creditCardService.GetMoney(3)); // a new ValueTask
    

    The following would be awaiting a single task multiple times:

    var creditCardService = new CreditCardService();
    var money1Task = creditCardService.GetMoney(1)
    Console.WriteLine(await money1Task);
    Console.WriteLine(await money1Task);