named async lambda function
Asked Answered
M

1

6

I want to create within a function a named lambda function, so that I can call it repeatedly afterwards in the same function.

I used to do this synchronously/without tasks with

Func<string, bool> pingable = (url) => return pingtest(url);

but in this case I want to call the pingable function as a task, so I would need a Task return type.

This is where I am stuck.

For all below, I am getting compile errors:

   * Func<string, Task<bool>> pingable = (input) => { return pingtest(url); };
   * Task<bool> pingable = new Task<bool>((input) => { return pingtest(url); });

I can declare the function normally though, but then I cannot call it as a task:

   Func<string, bool> pingable = (input) => { return pingtest(url); };      
   var tasks = new List<Task>();
   * tasks.Add(async new Task(ping("google.de")));

All the lines I have marked with a * produce copmile errors.

http://dotnetcodr.com/2014/01/17/getting-a-return-value-from-a-task-with-c/ seems to have a hint at a solution, but the sample there does not allow for not provided input parameters. (Sample taken from there and simplified:)

Task<int> task = new Task<int>(obj => 
{
    return obj + 1;
}, 300);

How to create and call named Task lambdas in C#, and I would like to declare them on a function rather than class level.

I want the named lambda in order to call it multiple times (several urls in this case).


Edit/update since you asked for code:

Func<string, Task<bool>> ping = url => Task.Run(() =>
{
    try
    {
        Ping pinger = new Ping();
        PingReply reply = pinger.Send(url);
        return reply.Status == IPStatus.Success;
    }
    catch (Exception)
    {
        return false;
    }
});

var tasks = new List<Task>();
tasks.Add(ping("andreas-reiff.de"));
tasks.Add(ping("google.de"));
Task.WaitAll(tasks.ToArray());
bool online = tasks.Select(task => ((Task<bool>)task).Result).Contains(true);

This already makes use of the solution proposed here.

Muscat answered 5/1, 2015 at 20:22 Comment(2)
how does pingtest looks?Ghee
It is here just a shorthand for what I want to insert. I will add it in an edit, combined with your solution in a minute.Muscat
G
6

Since pingtest looks to be synchronous itself, I assume you want a Task so that the method would run on a different thread. If that's true you need to use Task.Run to offload the work to a ThreadPool thread:

Func<string, Task<bool>> func = url => Task.Run(() => pingtest(url));

For completeness, if pingtest was async (i.e. pingtestAsync) you would need to create an async lambda expression:

Func<string, Task<bool>> func = async url => await pingtestAsync(url);

However, since in this case pingtestAsync already return a Task<bool> there's no sense in adding another layer of async or a lambda expression at all. This would be enough:

Func<string, Task<bool>> func = pingtestAsync;
Ghee answered 5/1, 2015 at 20:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.