Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linq and Async Lambdas

The following code...

using System;
using System.Linq;
using System.Threading.Tasks;

namespace ConsoleAsync
{
    class Program
    {
        static void Main(string[] args)
        {
            MainAsync(args).Wait();
            Console.ReadLine();
        }

        static async Task MainAsync(string[] args)
        {
            int[] test = new[] { 1, 2, 3, 4, 5 };

            if (test.Any(async i => await TestIt(i)))
                Console.WriteLine("Contains numbers > 3");
            else
                Console.WriteLine("Contains numbers <= 3");
        }

        public static async Task<bool> TestIt(int i)
        {
            return await Task.FromResult(i > 3);
        }
    }
}

Gives you the following error:-

CS4010: Cannot convert async lambda expression to delegate type 'Func<int, bool>'. An async lambda expression may return void, Task or Task<T>, none of which are convertible to 'Func<int, bool>'.

On the line

if (test.Any(async i => await Test.TestIt(i)))

How do you work with Async Lambdas and linq?

like image 258
Mick Avatar asked Apr 06 '16 08:04

Mick


People also ask

What is the difference between Lambda and LINQ?

Language Integrated Query (LINQ) is feature of Visual Studio that gives you the capabilities yo query on the language syntax of C#, so you will get SQL kind of queries. And Lambda expression is an anonymous function and is more of a like delegate type.

Which is faster LINQ or Lambda?

There is no performance difference between LINQ queries and Lambda expressions.

Can Lambda be async?

Lambda functions can be invoked either synchronously or asynchronously, depending upon the trigger. In synchronous invocations, the caller waits for the function to complete execution and the function can return a value.

What is Lambda and LINQ functions?

A lambda expression is a convenient way of defining an anonymous (unnamed) function that can be passed around as a variable or as a parameter to a method call. Many LINQ methods take a function (called a delegate) as a parameter.


1 Answers

You can't out of the box with LINQ. But you can write a little extension method which can make this work:

public static class AsyncExtensions
{
    public static async Task<bool> AnyAsync<T>(
        this IEnumerable<T> source, Func<T, Task<bool>> func)
    {
        foreach (var element in source)
        {
            if (await func(element))
                return true;
        }
        return false;
    }
}

And consume it like this:

static async Task MainAsync(string[] args)
{
    int[] test = new[] { 1, 2, 3, 4, 5 };

    if (await test.AnyAsync(async i => await TestIt(i))
        Console.WriteLine("Contains numbers > 3");
    else
        Console.WriteLine("Contains numbers <= 3");
}

It does feel a little cumbersome to me, but it achieves your goal.

like image 154
Yuval Itzchakov Avatar answered Oct 20 '22 19:10

Yuval Itzchakov