I am reading Concurrency in C#
by Stephen Cleary in which there is an example that has puzzled me for a while.
Normally the LINQ Select method requires a lambda method that returns the value for the result collection.
In the book on page 30 there is an example where the lambda doesn't return anything, but nevertheless, the code compiles and runs fine:
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
The question is about this part:
var processingTasks = tasks.Select(async t =>
{
var result = await t;
Trace.WriteLine(result);
// Note: nothing is returned
}).ToArray();
Why is this? Is it a recommended approach?
UPDATE:
Where is this behaviour documented?
It's just like writing an async method that doesn't return a value, but uses a Task
to indicate completion:
public async Task FooAsync()
{
Console.WriteLine("Before");
await Task.Delay(1000);
Console.WriteLine("After");
}
As an async anonymous function, that would be:
Func<Task> foo = async () =>
{
Console.WriteLine("Before");
await Task.Delay(1000);
Console.WriteLine("After");
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With