Будет ли ValueTask по-прежнему полезен, если он зависит от метода, возвращающего задачу?

#c# #asynchronous #async-await #valuetask

Вопрос:

Используя следующие методы в качестве примера:

 public async ValueTask<int> MyMethod() {
    return await GetMyIntegerWithTask();
}

public async Task<int> GetMyIntegerWithTask() {
   if (/*in hot path*/) {
      return await SynchronousMethodThatUsesTask();
   } 
   return await AsynchronousMethodThatUsesTask();
}

public Task<int> SynchronousMethodThatUsesTask() {
   int value = new Random().Next();
   return Task.FromResult(value); 
}

public async Task<int> AsynchronousMethodThatUsesTask() {
   //some asynchronous calculation 
}
 

Имеет ли использование ValueTask в качестве возвращаемого типа MyMethod все еще преимущества, связанные с тем, ValueTask что я ожидаю, что большую часть времени мой код будет выполняться синхронно (даже если синхронный метод, от которого я Task зависю, скорее всего, не ValueTask будет )?

Ответ №1:

Имеет ли использование ValueTask в качестве возвращаемого типа myMethod преимущества, связанные с ValueTask, потому что я ожидаю, что большую часть времени мой код будет выполняться синхронно (даже если синхронный метод, от которого я зависю, возвращает задачу, а не ValueTask)?

Преимущества производительности ValueTask незначительны, если только вы не звоните сюда очень часто. Тем не менее, да, ValueTask по крайней мере, это позволит избежать Task выделения, а в синхронном случае также позволит избежать переноса структуры конечного автомата в кучу.

Было бы лучше , если бы и GetMyIntegerWithTask то и SynchronousMethodThatUsesTask другое также использовалось ValueTask<int> , но даже без этого MyMethod можно использовать ValueTask<int> , чтобы избежать, по крайней мере, некоторых распределений.