Почему асинхронная лямбда-выборка LINQ Select не требует возвращаемого значения - PullRequest
0 голосов
/ 26 февраля 2019

Я читаю Concurrency in C# Стивена Клири, в котором есть пример, который озадачил меня на некоторое время.

Обычно для метода LINQ Select требуется лямбда-метод, который возвращает значение для коллекции результатов.

В книге на стр. 30 есть пример, где лямбда-выражение ничего не возвращает, нотем не менее, код компилируется и работает нормально:

static async Task<int> DelayAndReturnAsync(int val)
{
   await Task.Delay(TimeSpan.FromSeconds(val));
   return val;
}

static async Task ProcessTasksAsync()
{
   // Create a sequence of tasks
   Task<int> taskA = DelayAndReturnAsync(2);
   Task<int> taskB = DelayAndReturnAsync(3);
   Task<int> taskC = DelayAndReturnAsync(1);

   var tasks = new[] { taskA, taskB, taskC };

   var processingTasks = tasks.Select(async t => 
   {
      var result = await t;
      Trace.WriteLine(result);
      // Note: nothing is returned
   }).ToArray();

   // Await all processing to complete
   await Task.WhenAll(processingTasks);
}

// Outputs:
// 1
// 2
// 3

Вопрос об этой части:

var processingTasks = tasks.Select(async t => 
   {
      var result = await t;
      Trace.WriteLine(result);
      // Note: nothing is returned
   }).ToArray();

Почему это так?Это рекомендуемый подход?

ОБНОВЛЕНИЕ:

Где это поведение документировано?

1 Ответ

0 голосов
/ 26 февраля 2019

Это похоже на написание асинхронного метода, который не возвращает значение, но использует Task для указания завершения:

public async Task FooAsync()
{
    Console.WriteLine("Before");
    await Task.Delay(1000);
    Console.WriteLine("After");
}

В качестве асинхронной анонимной функции это будет:

Func<Task> foo = async () =>
{
    Console.WriteLine("Before");
    await Task.Delay(1000);
    Console.WriteLine("After");
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...