为什么异步LINQ Select lambda不需要返回值

时间:2019-02-26 16:04:11

标签: c# linq asynchronous select

我正在阅读Stephen Cleary的Concurrency in C#,其中有一个例子使我有些困惑。

通常,LINQ Select方法需要一个lambda方法,该方法返回结果集合的值。

在第30页的书中,有一个示例,其中lambda不返回任何内容,但是代码可以编译并正常运行:

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 :(得分:7)

就像编写异步方法一样,该方法不返回值,但使用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");
};